正题
题目链接:
https://www.luogu.org/problem/P4318
https://www.lydsy.com/JudgeOnline/problem.php?id=2440
题目大意
完全平方数只对应任意一个的正整数满足
d
∣
n
,
d
2
∤
n
d\mid n,d^2\nmid n
d∣n,d2∤n(也就是
n
n
n的质因数分解后都没有次数)。
求第
k
k
k个完全平方数
解题思路
考虑二分答案,将问题转换为判定求
1
∼
m
i
d
1\sim mid
1∼mid内有多少个完全平方数。
考虑容斥,我们考虑用
1
∼
m
i
d
1\sim \sqrt mid
1∼mid这些数中的无平方因子数进行容斥。而因为会有重复,我们发现对应
x
x
x来说的容斥系数就是
μ
(
x
)
\mu (x)
μ(x)(首先保证了一定是无平方因子数,然后若只有一个质因数
μ
(
x
)
=
−
1
\mu(x)=-1
μ(x)=−1否则
μ
(
x
)
=
1
\mu(x)=1
μ(x)=1这样就是容斥系数了)。而对应
x
x
x来说可以组成
⌊
n
x
2
⌋
\lfloor \frac{n}{x^2}\rfloor
⌊x2n⌋个平方因子数,所以个数为
∑
i
=
1
m
μ
(
x
)
⌊
m
i
d
i
2
⌋
\sum_{i=1}^{\sqrt m}\mu(x)\lfloor \frac{mid}{i^2}\rfloor
i=1∑mμ(x)⌊i2mid⌋
c o d e code code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=100010;
ll T,n,l,r,mu[N+10],prime[N+10],cnt;
bool v[N+10];
ll check(ll n)
{
ll ans=0;
for(ll i=1;i*i<=n;i++)
ans+=mu[i]*(n/(i*i));
return ans;
}
int main()
{
scanf("%lld",&T);
mu[1]=1;
for(ll i=2;i<=N;i++){
if(!v[i])mu[i]=-1,prime[++cnt]=i;
for(ll j=1;j<=cnt&&i*prime[j]<=N;j++){
v[i*prime[j]]=1;
if(!(i%prime[j])) break;
mu[i*prime[j]]=-mu[i];
}
}
while(T--){
scanf("%lld",&n);
l=1;r=2*n;
while(l<=r){
ll mid=(l+r)/2;
if(check(mid)>=n) r=mid-1;
else l=mid+1;
}
printf("%lld\n",l);
}
}