vijos1889 天真的因数分解(莫比乌斯反演+二分答案)

来源:互联网 发布:地方债务数据 2016 编辑:程序博客网 时间:2024/05/21 09:39

求第k个mu为0的数,k<=1e10,所以O(n)肯定也挂。考虑不合格的数,就是含有一个平方因子的数。设F(x)表示1~x中不合格的数,则根据容斥原理,利用莫比乌斯函数,我们可以得到F[x]=i=2xx/i2]μ(i),然后就是喜闻乐见的分块啦~(直接暴力算也是可以的。。。)复杂度O(nlog51010)
tips:注意ll,死了好久。

#include <bits/stdc++.h>using namespace std;#define ll long long#define inf 0x3f3f3f3f#define N 1000010inline ll read(){    ll x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();    return x*f;}int prime[N],tot=0;bool notprime[N];ll kk,mu[N];void Mobius(){    memset(notprime,0,sizeof(notprime));    notprime[1]=1;mu[1]=1;    for(int i=2;i<=N-10;++i){        if(!notprime[i]){            prime[++tot]=i;mu[i]=-1;        }        for(int j=1;prime[j]*i<=N-10;++j){            notprime[prime[j]*i]=1;            if(i%prime[j]==0){                mu[i*prime[j]]=0;break;            }mu[prime[j]*i]=-mu[i];        }    }for(int i=1;i<=N-10;++i) mu[i]+=mu[i-1];}ll F(ll x){    ll res=0;int last=0,n=sqrt(x);    for(ll i=2;i<=n;i=last+1){        last=sqrt(x/(x/(i*i)));last=min(last,n);        res+=(x/(i*i))*(mu[last]-mu[i-1]);    }return -res;}int main(){//  freopen("a.in","r",stdin);    kk=read();ll l=4,r=5LL*1e10;Mobius();    while(l<=r){        ll mid=l+r>>1;        if(F(mid)>=kk) r=mid-1;        else l=mid+1;    }    printf("%lld\n",r+1);    return 0;}
原创粉丝点击