Eddy's爱好
Time Limit: 1000ms
Memory Limit: 32768KB
This problem will be judged on HDU. Original ID: 220464-bit integer IO format: %I64d Java class name: Main
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
解题:容斥原理来一发
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int maxn = 100; 5 vector<int>g; 6 const int p[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67}; 7 void init(int r = 64) { 8 g.clear(); 9 for(int i = 0; p[i] < r; ++i) { 10 for(int j = g.size()-1; j >= 0; --j) 11 if(abs(p[i]*g[j]) <= 63) g.push_back(-p[i]*g[j]); 12 g.push_back(p[i]); 13 } 14 } 15 int main() { 16 LL x; 17 init(); 18 while(~scanf("%I64d",&x)) { 19 LL ret = 0; 20 for(int i = 0; i < g.size(); ++i) { 21 LL tmp = pow(x + .5,1.0/abs(g[i])); 22 if(g[i] < 0) ret -= tmp; 23 else ret += tmp; 24 } 25 printf("%I64d ",ret - 1); 26 } 27 return 0; 28 }