BZOJ 2440 完全平方数(莫比乌斯反演,容斥原理)
http://www.lydsy.com/JudgeOnline/problem.php?id=2440
题意:求第K个没有平方因子的数
思路:首先,可以二分数字,然后问题就转变成x以内有多少无平方因子的数
根据容斥原理:x以内无平方因子数=1*无需是任何质数的倍数的数数量-1*至少是1个质数的平方的倍数的数数量+1*至少是2个质数的平方的倍数的数量-1*至少是3个质数的平方的倍数的数量............然后发现,莫比乌斯函数u[i]正好满足:当i是不同的质数乘积时,返回-1,有相同因子就返回1,否则返回0
因此枚举i从1到根号x,ans+=mul[i]*x/(i*i)
1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 #define N 160000 7 #define ll long long 8 int mark[200005],p[200005],mul[200005]; 9 int read(){ 10 char ch=getchar();int t=0,f=1; 11 while (ch<'0'||ch>'9'){if (ch=='0') f=-1;ch=getchar();} 12 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 13 return t*f; 14 } 15 void init(){ 16 mul[1]=1; 17 for (int i=2;i<=N;i++){ 18 if (!mark[i]){ 19 p[++p[0]]=i; 20 mul[i]=-1; 21 } 22 for (int j=1;j<=p[0]&&p[j]*i<=N;j++){ 23 mark[i*p[j]]=1; 24 if (i%p[j]) mul[i*p[j]]=-mul[i]; 25 else{ 26 mul[i*p[j]]=0; 27 break; 28 } 29 } 30 } 31 } 32 ll cal(ll x){ 33 ll sum=0; 34 for (ll i=1;i*i<=x;i++) 35 sum+=x/(i*i)*mul[(int)i]; 36 return sum; 37 } 38 int main(){ 39 init(); 40 int T=read(); 41 while (T--){ 42 ll K=(ll)read(); 43 ll L=K,R=1644934081LL,ans=0; 44 while (L<=R){ 45 ll mid=(L+R)>>1; 46 if (cal(mid)>=K) ans=mid,R=mid-1; 47 else L=mid+1; 48 } 49 printf("%lld\n",ans); 50 } 51 }