Description
小 X 自幼就很喜欢数。但奇怪的是,他十分讨厌完全平方数。他觉得这些
数看起来很令人难受。由此,他也讨厌所有是完全平方数的正整数倍的数。然而
这丝毫不影响他对其他数的热爱。
这天是小X的生日,小 W 想送一个数给他作为生日礼物。当然他不能送一
个小X讨厌的数。他列出了所有小X不讨厌的数,然后选取了第 K个数送给了
小X。小X很开心地收下了。
然而现在小 W 却记不起送给小X的是哪个数了。你能帮他一下吗?
题解
- 二分答案,将问题转换为求[1,m]种有多少个无平方因子数
- 没有平方因子不就是μ(i)!=0
- 根据容斥原理,满足要求的ans=n-只有一个质数因子次数大于等于2的个数+只有2个质数因子大于等于2的个数-...
代码
1 #include <cmath>
2 #include <cstdio>
3 #include <iostream>
4 #define ll long long
5 using namespace std;
6 const ll N=100010,inf=(1<<31)-1;
7 ll T,n,l,r,ans,mobius[N],p[N],bz[N];
8 bool check(ll x) { ll r=0; for (ll i=1;i<=sqrt(x);i++) r+=mobius[i]*x/(i*i); return r>=n; }
9 int main()
10 {
11 scanf("%lld",&T),mobius[1]=1;
12 for (ll i=2;i<=N;i++)
13 {
14 if (!bz[i]) mobius[i]=-1,p[++p[0]]=i;
15 for (ll j=1;j<=p[0]&&i*p[j]<=N;j++)
16 {
17 bz[i*p[j]]=1;
18 if (i%p[j]) mobius[i*p[j]]=-mobius[i]; else { mobius[i*p[j]]=0; break; }
19 }
20 }
21 for (;T;T--)
22 {
23 scanf("%lld",&n),l=1,r=ans=inf;
24 while (l<=r)
25 {
26 ll mid=l+r>>1;
27 if (check(mid)) ans=mid,r=mid-1; else l=mid+1;
28 }
29 printf("%lld\n",ans);
30 }
31 }