[容斥+莫比乌斯]bzoj2440_完全平方数

来源:互联网 发布:人工智能 大学排名 编辑:程序博客网 时间:2024/05/01 16:26
其实这道题只是莫比乌斯函数的应用,并没有反演。。。
      题目意思就是说找到第k个不是完全平方数正整数倍的数。
      找这个数,我们肯定想到了二分答案是不是?对,就是他,此时我们把问题转化为了[1,x]中有几个不是完全平方数正整数倍的数
      然后我们就会想到用容斥去做
      + 0个质因子的倍数(1的倍数)
      - 1个质因子平方的倍数(4的倍数,9的倍数,25的倍数。。。)
      +2个质因子平方的倍数(36的倍数,100的倍数。。。)
                                   。。。。。。
    然后发现和莫比乌斯函数表示的形式是一样的。
    然后这题就这样解出来了
    1.线性筛出莫比乌斯函数(1,sqrt(2*10^9))听说有人证明了答案一定是小于2n的,本人不才,不会证。。。
    2.二分答案ans,然后容斥求有几个数,然后就可以了。
贴代码:
 
#include<cstdio>#include<cstdlib>#include<iostream>#include<cmath>#include<cstring>#define ll long long using namespace std;ll T,n;int prime[100000];int miu[100000];bool bo[100000];void makemiu(){memset(bo,true,sizeof(bo));    miu[1]=1;int tot=0;for(int i=2;i<=100000;i++) { if(bo[i]) prime[++tot]=i,miu[i]=-1; for(int j=1;j<=tot&&prime[j]*i<=100000;j++)  {  bo[prime[j]*i]=0;  if(i%prime[j]==0)   {   miu[i*prime[j]]=0;   break;   }miu[i*prime[j]]=-miu[i];  } }}ll pd(ll u){ll ans=0;int sqr=sqrt(u);for(int i=1;i<=sqr;i++) ans+=miu[i]*(u/(i*i));return ans;}ll find(ll n){ll l=1,r=n*2;while(l<r-1) { int mid=l+r>>1; if(pd(mid)<n)  l=mid; else  r=mid; } return r;}int main(){scanf("%lld",&T);makemiu();while(T--) { scanf("%lld",&n); printf("%lld\n",find(n)); }return 0;}


0 0
原创粉丝点击