[莫比乌斯函数][容斥]BZOJ 2440 完全平方数

https://www.luogu.org/problem/P4318

分析

可以转化为二分m求[1,m]中有多少个无平方因子数

显然可以容斥:0个质数的平方个数-1个质数的平方个数+2个的……

容易发现容斥系数是莫比乌斯函数

线性筛预处理再二分即可

注意二分l,r,mid可能超出longlong范围

最终公式:

$ans=\sum _{i=1}^{\left \lfloor \sqrt{n} \right \rfloor} \mu (i)\left \lfloor \frac{n}{i^2} \right \rfloor$

 

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
const int Inf=2147483647;
const int N=46341;
int T,k;
int prime[N],miu[N],cnt;
bool nonprime[N];

void Prime() {
    miu[1]=1;
    for (int i=2;i<N;i++) {
        if (!nonprime[i]) prime[++cnt]=i,miu[i]=-1;
        for (int j=1;j<=cnt;j++) {
            if (i*prime[j]>=N) break;
            nonprime[i*prime[j]]=1;
            if (i%prime[j]==0) {
                miu[i*prime[j]]=0;
                break;
            }
            miu[i*prime[j]]=-1*miu[i];
        }
    }
}

bool Check(ll mid) {
    ll n=sqrt(mid),ans=0;
    for (int i=1;i<=n;i++) ans+=1ll*miu[i]*(mid/(i*i));
    return ans>=k;
}

int main() {
    Prime();
    for (scanf("%d",&T);T;T--) {
        scanf("%d",&k);
        ll l=1,r=Inf,mid,ans;
        while (l<=r) {
            mid=1ll*(l+r)>>1;
            if (Check(mid)) ans=mid,r=mid-1;
            else l=mid+1;
        }
        printf("%lld\n",ans);
    }
}
View Code

 

posted @ 2019-08-17 07:40  Vagari  阅读(171)  评论(0编辑  收藏  举报