hdu 2204 Eddy's爱好 容斥原理


给你一个正整数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<stdio.h>
int prime[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59};
LL n;
LL dfs(LL x,LL y,int idx,int flag)
{
    if(flag >= 3) return 0;
    LL ret = 0;
    for(int i = idx; i < 17; ++i)
        ret += (LL)(pow(x,1.0/prime[i]/y)+eps) - 1 - dfs(x,y*prime[i],i+1,flag+1);
    return ret;
}
int main()
{
    while(~scanf("%I64d",&n))
    {
        printf("%I64d\n",dfs(n,1,0,0)+1);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值