[bzoj2440]完全平方数[中山市选2011][莫比乌斯函数][线性筛][二分答案]
题意:求第k个分解质因子后质因子次数均为一的数,即求第k个无平方因子数。
题解:
首先二分答案mid,那么现在就是要求出mid以内的无平方因子数的个数。
其次枚举$\sqrt{mid}$内的所有质数,由容斥原理
$Num=0个质数平方的倍数的数量(1的倍数)-1个质数平方的倍数的数量(9,25...的倍数)$
$+2个质数平方的倍数的数量(36,100...的倍数)...$
可以发现对于一个数x,x的倍数数量对答案的贡献符号为$\mu(x)$。
例如:9的倍数数量最答案的贡献是$\mu(9)\lfloor{\frac{mid}{9}}\rfloor=-\lfloor{\frac{mid}{9}}\rfloor$
所以最终mid以内的个数为
$Cnt=\sum\limits^{\lfloor{\sqrt{mid}}\rfloor}_{i=1}(\mu(i)\lfloor{\frac{mid}{i^2}}\rfloor)$
其中莫比乌斯函数为积性函数所以可以用线性筛预处理。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 int T,n,p[51000],Mu[51000],noprime[51000]; 6 bool visited[51000]; 7 8 void Mobius(const int N) 9 { 10 int pnum=0; Mu[1]=1; 11 for(int i=2;i<N;i++) 12 { 13 if(!visited[i]) { p[pnum++]=i; Mu[i]=-1; } 14 for(int j=0;j<pnum && i*p[j]<N;j++) 15 { 16 visited[i*p[j]]=true; 17 if(i%p[j]==0) { Mu[i*p[j]]=0; break; } 18 Mu[i*p[j]]=-Mu[i]; 19 } 20 } 21 } 22 23 int Check(const int x) 24 { 25 int temp=sqrt(x),Ans=0; 26 for(int i=1;i<=temp;++i) 27 Ans+=Mu[i]*(x/i/i); 28 return Ans; 29 } 30 31 int main() 32 { 33 scanf("%d",&T); Mobius(50000); 34 while(T--) 35 { 36 scanf("%d",&n); 37 int l=0,r=2e9; 38 while(l<r-1) 39 { 40 int mid=l+((r-l)>>1); 41 if(Check(mid)>=n)r=mid; 42 else l=mid; 43 } 44 printf("%d\n",r); 45 } 46 return 0; 47 }