[BZOJ2440][中山市选2011]完全平方数
题目大意:
$q(q\leq50)$组询问,每次询问第$k(k\leq10^9)$个不含平方因子的数。
思路:
二分答案+莫比乌斯反演。
若用$c_i$表示$i$个指数质数平方的倍数的数量,则$n以内不含平方因子的数的个数=\sum(-1)^ic_i=\sum_{i=1}^{\lfloor\sqrt n\rfloor}\lfloor\frac n{i^2}\rfloor\mu(p)$。
1 #include<cstdio> 2 #include<cctype> 3 inline int getint() { 4 register char ch; 5 while(!isdigit(ch=getchar())); 6 register int x=ch^'0'; 7 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 8 return x; 9 } 10 const int N=40558,M=4252; 11 bool vis[N]; 12 int mu[N],p[M]; 13 inline void sieve() { 14 mu[1]=1; 15 for(register int i=2;i<N;i++) { 16 if(!vis[i]) { 17 p[++p[0]]=i; 18 mu[i]=-1; 19 } 20 for(register int j=1;j<=p[0]&&i*p[j]<N;j++) { 21 vis[i*p[j]]=true; 22 if(i%p[j]==0) { 23 mu[i*p[j]]=0; 24 break; 25 } else { 26 mu[i*p[j]]=-mu[i]; 27 } 28 } 29 } 30 } 31 inline int calc(const int &n) { 32 int ret=0; 33 for(register int i=1;i*i<=n;i++) { 34 ret+=n/(i*i)*mu[i]; 35 } 36 return ret; 37 } 38 int main() { 39 sieve(); 40 for(register int T=getint();T;T--) { 41 const int k=getint(); 42 unsigned l=1,r=1644934081; 43 while(l<=r) { 44 const int mid=(l+r)>>1; 45 if(calc(mid)>=k) { 46 r=mid-1; 47 } else { 48 l=mid+1; 49 } 50 } 51 printf("%u\n",r+1); 52 } 53 return 0; 54 }