hdu2204 Eddy's爱好

Wesley13
• 阅读 488

原题:点击打开链接

题意很明确了,即:给你一个正整数N,确定在1到N之间有多少个可以表示成M^K(K>1)的数。

本题目为容斥原理题目,容斥原理的伪代码如下:

void dfs(int cur , int cmn, int id)
{
    1.计算当前集合|cmn|的个数;
    2.判断id的奇偶,以此判定+或者-, 此处id的判断方法可用(id & 1)位运算来判断;
    3.dfs(cur+1, 重复集合, id + 1); 例子:如果之前计算了p(a),p(b), 即计算p(a)+p(b)-p(a交b);
}

姑且这么解释,希望读者能够看懂。

分析本题:

如何避免重复计算:

1.即M的次方为质数。K如果是质数,就不能拆分成为两个数的乘积,减少了部分重复;

2.还有一种重复是类似与4 ^3 与 8 ^ 2的重复(对于容斥来讲,就是2 ^ (2*3),这种重复就得利用容斥原理清除。

3.离散数学学得好的可以用代数系统考虑。

特殊知识:pow(n, 1 / num)可以用于开方。

//============================================================================
// Name        : hdu2204.cpp
// Author      :
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;
#define lln long long int

lln prime[20] = {2, 3, 5, 7, 11, 13, 17, 19 ,23, 29, 31, 37, 41, 43, 47, 53, 57,59 ,61};//打表质数,因为2 ^60次方 > 10 ^18
lln ans, tmp, n;


void dfs(int cur, int cmn, int id){
    if(id >= 4)//2 ^ (2 * 5 * 7 = 70 )
        return;
    lln num, i;
    for(i = cur; i < 19; i++){
        num = (lln) pow(n, 1 / (prime[i] * cmn));    //find the same key; pow a ^(1/n) 学到了。
        if(id & 1)                             // id odd, minus or add
            ans += num;
        else
            ans -= num;
        dfs(i+1, cmn * prime[i], id+1);
        //find other
    }
}


void ace(){
    while (cin >> n) {
        ans = 0;
        dfs(0, 1, 1);
        printf("%I64d\n", ans);
    }
}

int main() {
    ace();
    return 0;
}
点赞
收藏
评论区
推荐文章
先知 先知
3年前
C 语言代码大全
1两个数组的合并题目描述已知数组a中有m个按升序排列的元素,数组b中有n个按降序排列的元素,编程将a与b中的所有元素按降序存入数组c中。输入输入有两行,第一行首先是一个正整数m,然后是m个整数;第二行首先是一个正整数n,然后是n个整数,m,n均小于等于1000000。输出输出合并后的mn个整数,数据之间用空格隔开。输出占一行。样例输入4
DaLongggggg DaLongggggg
3年前
python-算法训练 区间k大数查询
问题描述给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个。输入格式第一行包含一个数n,表示序列长度。第二行包含n个正整数,表示给定的序列。第三个包含一个正整数m,表示询问个数。接下来m行,每行三个数l,r,K,表示询问序列从左往右第l个数到第r个数中,从大往小第K大的数是哪个。序列元素从1开始标号。输出格式总共输出m行,每行一个数
DaLongggggg DaLongggggg
3年前
python刷题-进制转换
十六进制转八进制问题描述  给定n个十六进制正整数,输出它们对应的八进制数。输入格式  输入的第一行为一个正整数n(1<n<10)。  接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。输出格式  输出n行,每行为输入对应的八进制正整数。  【注意】  输入的十六进制数不会有
Stella981 Stella981
2年前
Codeforces 862B (二分图染色)
<题目链接(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fvjudge.net%2Fproblem%2FCodeForces862B)\题目大意:给出一个有n个点的二分图和n1条边,问现在最多可以添加多少条边使得这个图中不存在自环,重边,并且此图还是一个二
Stella981 Stella981
2年前
LeetCode 5561. 获取生成数组中的最大值
文章目录1\.题目2\.解题1\.题目给你一个整数n。按下述规则生成一个长度为n1的数组nums:nums00nums11当2<2i<n时,nums2inumsi
Stella981 Stella981
2年前
HDU1005 Number Sequence
HDU1005NumberSequence(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Facm.hdu.edu.cn%2Fshowproblem.php%3Fpid%3D1005)对于公式f\n\A\f\n1\B\f\n2\,因为对于f\n1\
Stella981 Stella981
2年前
POJ 1195 Mobile phones(二维树状数组)
题目链接:http://poj.org/problem?id1195(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fpoj.org%2Fproblem%3Fid%3D1195)题意是有四种操作。当n0时:输入一个m表示初始化矩阵(m\m且值都为0)。
Stella981 Stella981
2年前
GYM 101755 K.Video Reviews 【贪心】+【二分】
<题目链接(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fcodeforces.com%2Fgym%2F101755%2Fproblem%2FK)\题目大意:一家公司想让n个人给他们的产品评论,所以依次去找这n个人,第i个人会评论当且仅当已经有ai个人评论或他确
Wesley13 Wesley13
2年前
Java大数统计
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid1316(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Facm.hdu.edu.cn%2Fshowproblem.php%3Fpid%3D1316)题目描述:!(https://o
Stella981 Stella981
2年前
Hdu
Sequence(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Facm.hdu.edu.cn%2Fshowproblem.php%3Fpid%3D6395)