容斥原理是一个从小学就开始学习的算法。但是很多难题现在都觉得做的十分吃力。
容斥原理大概有两种表现形式,一种是按照倍数进行容斥,这个东西直接用莫比乌斯函数就可以了。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAXN 200100 typedef long long qword; bool pflag[MAXN]; int prime[MAXN],topp=-1; int mu[MAXN]; int a[MAXN],tota; int b[MAXN],totb; void init() { for (register int i=2;i<MAXN;i++) { if (!pflag[i]) { prime[++topp]=i; mu[i]=1; } for (register int j=0;j<=topp && i*prime[j]<MAXN;j++) { pflag[i*prime[j]]=true; if (i%prime[j]==0) { mu[i*prime[j]]=0; break; } mu[i*prime[j]]=-mu[i]; } } } int main() { //freopen("input.txt","r",stdin); qword tot; scanf("%lld\n",&tot); init(); for (register int i=1;i<MAXN;i++) if (mu[i]==1) a[tota++]=i; else if (mu[i]==-1) b[totb++]=i; register qword l,r,mid; register qword ans=0; l=0,r=26000000000LL; while (l+1<r) { mid=(l+r)>>1; ans=0; for (register int i=0;i<tota && (qword)a[i]*a[i]<=mid;i++) ans=ans+mid/((qword)a[i]*a[i]); for (register int i=0;i<totb && (qword)b[i]*b[i]<=mid;i++) ans=ans-mid/((qword)b[i]*b[i]); if (ans>=tot) r=mid; else l=mid; } printf("%lld\n",r); }