zoukankan      html  css  js  c++  java
  • HDU 2204 Eddy's爱好 (容斥原理)

    Eddy's爱好

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 900    Accepted Submission(s): 397

    Problem Description
    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
     
    Author
    Eddy
     
    Recommend
    lcy
     
     
     
     

    题意:给你一个正整数N,确定在1到N之间有多少个可以表示成M^K(K>1)的数。

    我们可以由n^(1/p),知道指数为p的有多少个数。

    通过观察,可以发现若一个数可以表示成x^(k*t),则可以表示成(x^k)^t。因此指数必然为素数。

    枚举素数便可以得到指数为p的个数,但是可能出现重复,例如:x^3=y^5,其中x=t^5,y=t^3。

    运用容斥原理,设a[i]表示指数为第i个素数的个数,那么答案等于满足一个的,减去两个的,加上三个的……

    由于2^60>10^18,2*3*5*7>60,所以只要枚举到三即可。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    
    using namespace std;
    
    const int N=65;
    #define eps 1e-8
    
    int prime[N],isprime[N];
    
    void getPrime(){
        int i,j;
        prime[0]=0;
        for(i=0;i<N;i++)
            isprime[i]=1;
        for(i=2;i<N;i++)
            if(isprime[i]){
                prime[++prime[0]]=i;
                for(j=2;i*j<N;j++)
                    isprime[i*j]=0;
            }
    }
    
    int main(){
    
        //freopen("input.txt","r",stdin);
    
        long long n,tmp;
        getPrime();
        while(cin>>n){
            int ans=1;
            for(int i=1;i<=prime[0];i++){
                tmp=(long long)(pow((double)n,1.0/prime[i])+eps);   //不加eps则WA
                if(tmp==1)      //减枝,下同
                    break;
                ans+=tmp-1;
            }
            for(int i=1;i<=prime[0];i++)
                for(int j=i+1;j<=prime[0];j++){
                    tmp=(long long)(pow((double)n,1.0/(prime[i]*prime[j]))+eps);
                    if(tmp==1)
                        break;
                    ans-=(tmp-1);
                }
            for(int i=1;i<=prime[0];i++)
                for(int j=i+1;j<=prime[0];j++)
                    for(int k=j+1;k<=prime[0];k++){
                        tmp=(long long)(pow((double)n,1.0/(prime[i]*prime[j]*prime[k]))+eps);
                        if(tmp==1)
                            break;
                        ans+=(tmp-1);
                    }
            printf("%d\n",ans);
        }
        return 0;
    }
  • 相关阅读:
    NUI四种提交数据方式c
    除Hadoop大数据技术外,还需了解的九大技术
    svn提交报错:svn: Aborting commit:XXXXXremains in conflict
    普元部署多个应用的方法(适用EOS6.5以上版本,且无需governor中添加应用)
    C#根据html生成PDF
    判断一个数值是否在一个逗号分隔的字符串中
    判断网站地址是否是http开头
    Date.prototype.format
    C#实现XML与DataTable互转
    C#读取Excel表格数据到DataGridView中和导出DataGridView中的数据到Excel
  • 原文地址:https://www.cnblogs.com/jackge/p/2995080.html
Copyright © 2011-2022 走看看