首页 > 代码库 > C - Eddy's爱好
C - Eddy's爱好
C -Eddy‘s爱好
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Description
Ignatius 喜欢收集蝴蝶标本和邮票,但是Eddy的爱好很特别,他对数字比较感兴趣,他曾经一度沉迷于素数,而现在他对于一些新的特殊数比较有兴趣。
这些特殊数是这样的:这些数都能表示成M^K,M和K是正整数且K>1。
正当他再度沉迷的时候,他发现不知道什么时候才能知道这样的数字的数量,因此他又求助于你这位聪明的程序员,请你帮他用程序解决这个问题。
为了简化,问题是这样的:给你一个正整数N,确定在1到N之间有多少个可以表示成M^K(K>1)的数。
这些特殊数是这样的:这些数都能表示成M^K,M和K是正整数且K>1。
正当他再度沉迷的时候,他发现不知道什么时候才能知道这样的数字的数量,因此他又求助于你这位聪明的程序员,请你帮他用程序解决这个问题。
为了简化,问题是这样的:给你一个正整数N,确定在1到N之间有多少个可以表示成M^K(K>1)的数。
Input
本题有多组测试数据,每组包含一个整数N,1<=N<=1000000000000000000(10^18).
Output
对于每组输入,请输出在在1到N之间形式如M^K的数的总数。
每组输出占一行。
每组输出占一行。
Sample Input
10 36 1000000000000000000
Sample Output
4 9 1001003332
意解:容斥原理,枚举指数k(k > 1),对于每一个指数,可以知道M^K<=N的最大M,然后因为当k为合数时,总是可以把其化为素数,所以只需枚举素数k,但是枚举过程会有重复,比如当x^2 = y ^ 3时,存在有数t(t>1)使得(t ^3) ^ 2 = (t ^2)^3 = t^6; 来到这里容易想到容斥原理,奇数加,偶数减;接下来就是对每一个k求解最大数M的过程了,如果直接通过枚举的话数据太大,会超时,所以可以把式子化为M<=N^(1/K),而这个可以直接利用cmath库函数中的pow函数求解M,不过因为pow参数是浮点型,所以需要注意精度问题,加上eps = 1e-8就行了.最后因为1也符合,所以结果加上一;
AC代码:
#include <iostream> #include <cstdio> #include <vector> #include <cmath> using namespace std; typedef long long ll; const double eps = 1e-8; vector<int>tmp; bool is_prime(int x) { for(int i = 2; i <= x / i; i++) if(x % i == 0) return false; return true; } int main() { ll N; while(cin>>N) { ll ans = 0; tmp.clear(); for(int i = 2; i <= 100; i++) { if(!is_prime(i)) continue; if((1LL << i) > N) break; tmp.push_back(i); } int len = tmp.size(); for(int i = 1; i < (1LL << len); i++) { ll mul = 1,tp = 0; for(int j = 0; j < len; j++) { if((i >> j) & 1) { mul *= tmp[j]; tp++; } } ll isGO = (ll)(pow((double)N,1.0 / mul) + eps) - 1; if(tp & 1) ans += isGO; else ans -= isGO; } cout<<ans + 1<<endl; } return 0; }
C - Eddy's爱好
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。