HDU 2204 Eddy's爱好(容斥原理)

Eddy's爱好

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


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
 
  
10361000000000000000000
 

Sample Output
 
  
491001003332



        就是求在n以内,有多少个数字可以表示为M^K的形式。

       如果考虑M的话,由于M可以很大,所以即使容斥也不现实。我们可以创造性的考虑观察这个指数K,因为这个指数K的取值要小于61。注意到如果有M^(ab)那么一定有(M^a)^b。什么意思呢?就是如果指数不是质数,那么一定可以每另外一组数字表示,且这组数字的指数是质数。所以说我们只需要统计指数是质数的数字能够组成多少个n以内的数字。显然,如果M^K<n,那么i^K<n,其中1<i<=M。于是每一个质数指数的贡献也就可以求出,即n^(1/K)-1,这里减一是指不计算M为1。
       但是,可以观察到,4^3=8^2,即使指数都是质数,还是会出现重复,原因在于4^3=2^6,8^2=2^6。即指数为6的数字既被2作为指数时计算,也被3作为指数时计算,故要利用容斥原理减去6作为指数的个数。又指数小于61,2*3*5*7=210>60,所以这个容斥的层数只有3层。直接用dfs进行暴力奇偶容斥即可。具体见代码:
#include<bits/stdc++.h>
#define LL long long
using namespace std;

LL prime[]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59};
LL ans,n,k;

void dfs(LL lcm,int i,int j)
{
    if (j==0)
    {
        LL tmp=pow(n,1.0/lcm);
        if (pow(tmp,0.0+lcm)>n) tmp--;
        if (--tmp>0)
        {
            if (k&1) ans+=tmp; else ans-=tmp;
        }
        return;
    }
    if (i==17) return;
    if (lcm*prime[i+1]<n) dfs(lcm*prime[i+1],i+1,j-1);
    dfs(lcm,i+1,j);
}

int main()
{
    while(~scanf("%I64d",&n))
    {
        ans=0;
        for(k=1;k<=3;k++)
            dfs(1,0,k);
        printf("%I64d\n",ans+1);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值