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;
}