题目传送门
题意
给出 T ( 1 ≤ T ≤ 50 ) T(1\le T\le 50) T(1≤T≤50)组询问,每次询问一个 K ( 1 ≤ K ≤ 1 0 9 ) K(1\le K\le 10^9) K(1≤K≤109),问你第 K K K个不是完全平方数的整数倍的数是多少?(完全平方数如 4 , 9 , 16... 4,9,16... 4,9,16...,不包含 1 1 1)。
思路
显然,
K
K
K和我们的答案之间是有单调性的,我们设
f
(
x
)
f(x)
f(x)为小于
x
x
x的合法的数的数量。
那么根据容斥原理,
f
(
x
)
=
∑
i
=
1
n
μ
(
i
)
∗
⌊
n
i
2
⌋
f(x)=\sum\limits_{i=1}^{\sqrt n}\mu(i)*\lfloor\cfrac{n}{i^2}\rfloor
f(x)=i=1∑nμ(i)∗⌊i2n⌋。
然后根据这个式子二分就可以了。
C o d e Code Code
// Author : ACfunhsl
// Time : 2021/5/17 14:13:11
#define int long long
const int N = 1e5+50;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
bool ok[N];
int p[N],cnt=0,mu[N];
void euler()
{
mu[1] = 1;
for(int i=2; i<N; i++)
{
if(!ok[i])
p[++cnt] = i,mu[i] = -1;
for(int j=1; j<=cnt&&p[j]*i<N; j++)
{
ok[i*p[j]] = 1;
if(i%p[j]==0)
{
mu[i*p[j]] = 0;
break;
}
else mu[i*p[j]] = -mu[i];
}
}
for(int i=2; i<N; i++)
mu[i] += mu[i-1];
}
int k;
bool check(int n)
{
int res = 0,m=sqrt(n);
for(int l=1,r; l<=m; l=r+1)
{
r = min(m,(int)sqrt(n/(n/(l*l))));
res += n/(l*l)*(mu[r]-mu[l-1]);
}
return res>=k;
}
signed main()
{
euler();
int t;
cin>>t;
while(t--)
{
cin>>k;
int l = k,r = k * 2,ans;
while(l<=r)
{
int mid = l+r>>1;
if(check(mid))
r = mid-1,ans=mid;
else l = mid+1;
}
cout<<ans<<endl;
}
return 0;
}