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

 

posted @ 2016-06-23 13:35  Gster  阅读(704)  评论(1编辑  收藏  举报