2440: [中山市选2011]完全平方数
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 4838 Solved: 2340
[Submit][Status][Discuss]
Description
小 X 自幼就很喜欢数。但奇怪的是,他十分讨厌完全平方数。他觉得这些
数看起来很令人难受。由此,他也讨厌所有是完全平方数的正整数倍的数。然而
这丝毫不影响他对其他数的热爱。
这天是小X的生日,小 W 想送一个数给他作为生日礼物。当然他不能送一
个小X讨厌的数。他列出了所有小X不讨厌的数,然后选取了第 K个数送给了
小X。小X很开心地收下了。
然而现在小 W 却记不起送给小X的是哪个数了。你能帮他一下吗?
Input
包含多组测试数据。文件第一行有一个整数 T,表示测试
数据的组数。
第2 至第T+1 行每行有一个整数Ki,描述一组数据,含义如题目中所描述。
Output
含T 行,分别对每组数据作出回答。第 i 行输出相应的
第Ki 个不是完全平方数的正整数倍的数。
Sample Input
1
13
100
1234567
Sample Output
19
163
2030745
HINT
对于 100%的数据有 1 ≤ Ki ≤ 10^9
, T ≤ 50
分析
莫比乌斯函数的一个应用。
首先二分答案,问题转化为求[1,x]之间有多少个无平方因子数。
根据容斥原理,答案就是
0个素数的乘积的平方的倍数的数量(1的倍数)-1个素数的乘积的平方的倍数的数量(9的倍数,25的倍数)+2个素数的乘积的平方的倍数的数量(36的倍数(2*3=6,6*6=36),100的倍数)....
发现每个乘积a前面的系数就是μ(a)
$Q(x)=\sum\limits_{i=1}^{\biggl\lfloor\sqrt{x}\biggr\rfloor}μ(i)\biggl\lfloor\frac{x}{i^2}\biggr\rfloor$
参考 popoqqq的文章
code
1 #include<cstdio> 2 #include<cmath> 3 4 const int N = 100000; 5 typedef long long LL; 6 7 int prime[N+10],mu[N+10]; 8 bool noprime[N+10]; 9 int tot,T; 10 LL k; 11 12 void getmu() { 13 mu[1] = 1; 14 for (int i=2; i<=N; ++i) { 15 if (!noprime[i]) prime[++tot] = i,mu[i] = -1; 16 for (int j=1; j<=tot&&i*prime[j]<=N; ++j) { 17 noprime[i * prime[j]] = true; 18 if (i % prime[j]==0) {mu[i * prime[j]] = 0;break;} 19 mu[i * prime[j]] = -mu[i]; 20 } 21 } 22 } 23 24 bool check(int x) { 25 int g = sqrt(x);LL ans = 0; 26 for (int i=1; i<=g; ++i) { 27 ans += mu[i] * (x/i/i); 28 } 29 return ans >= k; 30 } 31 32 int main () { 33 getmu(); 34 scanf("%d",&T); 35 while (T--) { 36 scanf("%lld",&k); 37 LL L = 1,R = 2e9,ans; 38 while (L <= R) { 39 int mid = (L + R) / 2; 40 if (check(mid)) R = mid-1,ans = mid; 41 else L = mid + 1; 42 } 43 printf("%lld\n",ans); 44 } 45 return 0; 46 }