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 1000000000000000000Sample Output
4 9 1001003332
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<iostream> #define bug(x) printf("%d***\n",x) using namespace std; typedef long long ll; const double eps=1e-9; int num[70],vis[70]; int cnt; void get_pri(){ for(int i=2;i<=60;i++){ if(!vis[i]){ num[cnt++]=i; for(int j=i*i;j<=60;j+=i){ vis[j]=1; } } } } ll res,n; void dfs(int cur,int has,int need,int p){ if(cur>cnt||has>need||p>60)return;// 当前的cnt是还没有选的,真是sb if(has==need){ ll tmp=pow(n,1.0/p);//这种來蒙的话,可能有点难受,我们应该来验证,是不是应该剪掉一个1 if(pow(tmp,0.0+p)-n>eps)tmp--; tmp--; if(tmp>0)res+=tmp; return; } dfs(cur+1,has+1,need,p*num[cur]); dfs(cur+1,has,need,p); } /* 10 36 1000000000000000000 */ int main(){ cnt=0; get_pri(); ios::sync_with_stdio(false); while(cin>>n){ ll ans=1; for(int i=1;i<=3;i++){ res=0; dfs(0,0,i,1); if(i&1) ans+=res; else ans-=res; } cout<<ans<<endl; } return 0; }