[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 }

 

posted @ 2018-02-25 14:06  skylee03  阅读(104)  评论(0编辑  收藏  举报