Eddy's爱好 HDU - 2204

Ignatius 喜欢收集蝴蝶标本和邮票,但是Eddy的爱好很特别,他对数字比较感兴趣,他曾经一度沉迷于素数,而现在他对于一些新的特殊数比较有兴趣。
这些特殊数是这样的:这些数都能表示成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

Eddy's爱好 HDU - 2204_第1张图片

#include
#include
#include
#include
#include
#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<


你可能感兴趣的:(....容斥原理)