【BZOJ】【2440】【中山市选2011】完全平方数

莫比乌斯函数/容斥原理

  PoPoQQQ讲义引入例题= =

  比较水……就是莫比乌斯函数的简单应用,也可理解为乱容斥一下……

  二分答案——>求1~x有多少个无平方因子的数Q(x)。

 

引用一下PoPoQQQ的题解:

•根据容斥原理可知 对于sqrt(x)以内所有的质数 有
•  x以内的无平方因子数
•=0个质数乘积的平方的倍数的数的数量(1的倍数)
•-每个质数的平方的倍数的数的数量(9的倍数,25的倍数,...)
•+每2个质数乘积的平方的倍数的数的数量(36的倍数,100的倍数,...)-...
•容易发现每个乘积a前面的符号恰好是(例如故9对答案的贡献为负;,故36对答案的贡献为正)
•x以内i^2的倍数有个 故有
 1 /**************************************************************
 2     Problem: 2440
 3     User: Tunix
 4     Language: C++
 5     Result: Accepted
 6     Time:2360 ms
 7     Memory:10060 kb
 8 ****************************************************************/
 9  
10 //BZOJ 2440
11 #include<cstdio>
12 #include<cstdlib>
13 #include<cstring>
14 #include<iostream>
15 #include<algorithm>
16 #define rep(i,n) for(int i=0;i<n;++i)
17 #define F(i,j,n) for(int i=j;i<=n;++i)
18 #define D(i,j,n) for(int i=j;i>=n;--i)
19 using namespace std;
20  
21 int getint(){
22     int v=0,sign=1; char ch=getchar();
23     while(ch<'0'||ch>'9') {if (ch=='-') sign=-1; ch=getchar();}
24     while(ch>='0'&&ch<='9') {v=v*10+ch-'0'; ch=getchar();}
25     return v*=sign;
26 }
27 /*******************tamplate********************/
28 const int N=1e6+10;
29 typedef long long LL;
30 int mu[N],prime[N];
31 bool check[N];
32 void getmu(int n){
33     int tot=0;
34     mu[1]=1;
35     for(int i=2;i<n;++i){
36         if (!check[i]){
37             prime[tot++]=i;
38             mu[i]=-1;
39         }
40         rep(j,tot){
41             if (i*prime[j]>n) break;
42             check[i*prime[j]]=1;
43             if (i%prime[j]) mu[i*prime[j]]=-mu[i];
44             else{
45                 mu[i*prime[j]]=0;
46                 break;
47             }
48         }
49     }
50 }
51 int judge(int x){
52     int ans=0;
53     for(int i=1;i*i<=x;i++)
54         ans+=mu[i]*((LL)x/(i*i));
55     return ans;
56 }
57 int main(){
58     int T=getint(),n;
59     getmu(N-2);
60     while(T--){
61         n=getint();
62         int l=1,r=n*2,mid=0,now=0;
63         while(l<r){
64             mid=l+(r-l>>1);
65             now=judge(mid);
66             if (now<n) l=mid+1;
67             else r=mid;
68         }
69         printf("%d\n",l);
70     }
71     return 0;
72 }
View Code

 

posted @ 2015-02-22 19:09  Tunix  阅读(298)  评论(0编辑  收藏  举报