BZOJ2440完全平方数(莫比乌斯反演)
Description
小 X 自幼就很喜欢数。但奇怪的是,他十分讨厌完全平方数。他觉得这些
数看起来很令人难受。由此,他也讨厌所有是完全平方数的正整数倍的数。然而
这丝毫不影响他对其他数的热爱。
这天是小X的生日,小 W 想送一个数给他作为生日礼物。当然他不能送一
个小X讨厌的数。他列出了所有小X不讨厌的数,然后选取了第 K个数送给了
小X。小X很开心地收下了。
然而现在小 W 却记不起送给小X的是哪个数了。你能帮他一下吗?
Input
包含多组测试数据。文件第一行有一个整数 T,表示测试
数据的组数。
第2 至第T+1 行每行有一个整数Ki,描述一组数据,含义如题目中所描述。
Output
含T 行,分别对每组数据作出回答。第 i 行输出相应的
第Ki 个不是完全平方数的正整数倍的数。
Sample Input
4
1
13
100
1234567
1
13
100
1234567
Sample Output
1
19
163
2030745
19
163
2030745
HINT
对于 100%的数据有 1 ≤ Ki ≤ 10^9
, T ≤ 50
题解:
题目大意:求第k个无平方因子数是多少(无视原题干,1也是完全平方数那岂不是一个数也送不出去了?
无平方因子数(square-free number),即质因数分解之后所有质因数的次数都为1的数
首先二分答案 问题转化为求x以内有多少个无平方因子数
根据容斥原理可知 对于√x以内的所有质数 x以内的无平方因子数=无需是任何质数的倍数的数的数量(即x)-是至少一个质数平方倍数的数的数量+是至少两个质数平方倍数的数的数量-是至少三个质数平方倍数的数的数量...
我们回去考虑莫比乌斯函数,我们发现每一个质数乘积的符号与莫比乌斯函数的符号恰好吻合!
于是我们枚举每一个数,如果这个数是奇数个不同质数的乘积,那么mu为负,偶数个则mu为正,否则mu为零
故答案即Σx/(i*i)*mu[i]
1 /************************************************************** 2 Problem: 2440 3 User: SongHL 4 Language: C++ 5 Result: Compile_Error 6 ****************************************************************/ 7 8 9 #include<bits/stdc++.h> 10 using namespace std; 11 typedef long long ll; 12 const int maxn=5e4+10; 13 ll Prime[maxn],mob[maxn],vis[maxn],cnt; 14 int T,K; 15 16 void Mobius() 17 { 18 memset(Prime,0,sizeof Prime); 19 memset(mob,0,sizeof mob); 20 memset(vis,0,sizeof vis); 21 mob[1]=1; cnt=0; 22 for(ll i=2;i<maxn;++i) 23 { 24 if(!vis[i]) Prime[cnt++]=i,mob[i]=-1; 25 for(ll j=0;j<cnt&&i*Prime[j]<maxn;++j) 26 { 27 vis[i*Prime[j]]=1; 28 if(i%Prime[j]) mob[i*Prime[j]]=-mob[i]; 29 else { mob[i*Prime[j]]=0; break;} 30 } 31 } 32 } 33 34 int work(int x) 35 { 36 int ans=0; 37 for(int i=1;i*i<=x;++i) ans+=x/(i*i) * mob[i]; 38 return ans; 39 } 40 41 int Judge() 42 { 43 int l=1,r=K<<1,mid; 44 while(l+1<r) 45 { 46 mid=(l>>1)+(r>>1) +(l&r&1); 47 if(work(mid)>=K) r=mid; 48 else l=mid; 49 } 50 if(work(l)>=K) return l; 51 return r; 52 } 53 54 int main() 55 { 56 scanf("%d",&T); 57 Mobius(); 58 while(T--) { scanf("%d",&K); printf("%d\n",Judge()); } 59 return 0; 60 }