BZOJ2440: [中山市选2011]完全平方数 容斥原理+莫比乌斯函数

显然,二分答案 $mid$,求 $1$ ~ $mid$ 中完全平方数倍数的个数.
假设完全平方数是 $p^2$,则有 $\frac{mid}{p^2}$ 个不合法的.
但是直接枚举 $p$ 然后这么去算的话可能会算重,所以考虑容斥.
容斥的时候可以只枚举 $p$ 中不存在完全平方数的情况,这样我们在容斥的时候一个数被贡献的次数就和其 $p^2$ 中 $p$ 的因子种类有关.
容斥系数是 $(-1)^{|S|}$,即 $\mu(x)$ 函数.

#include <cstdio>
#include <algorithm>
#include <cmath> 
#include <cstring>
#define setIO(s) freopen(s".in","r",stdin)
#define maxn 50080  
const long long inf = 1844387848;  
#define ll long long 
using namespace std; 
int mu[maxn],vis[maxn],prime[maxn],tot; 
int main(){
    //setIO("input"); 
    mu[1]=1; 
    for(int i=2;i<maxn;++i) {
        if(!vis[i]) prime[++tot]=i,mu[i]=-1; 
            for(int j=1;j<=tot&&(ll)prime[j]*i < (ll) maxn; ++j) {
                vis[prime[j]*i] = 1;  
                if(i % prime[j]==0) { mu[prime[j]*i] = 0; break;  }
                mu[prime[j]*i] = -mu[i];  
            }
    }      
    int T;
    long long k; 
    long long l,r,ans;  
    scanf("%d",&T); 
    while(T--){
        scanf("%lld",&k);
        l=1,r=inf,ans=0; 
        while(l <= r) {
            long long mid=(l+r)>>1;        
            long long tmp=0; 
            for(ll i=1;i*i<=mid;++i) 
                tmp+=mu[i]*(mid/(i*i)) ;   
            if(tmp>=k) r = mid-1,ans=mid; 
            else l = mid + 1; 
        }
        printf("%lld\n",ans); 
    }
    return 0; 
}

  

posted @ 2019-02-25 20:13  EM-LGH  阅读(141)  评论(0编辑  收藏  举报