problem
求出第 k k k 个不含平方因子(即不是完全平方数的倍数)的正整数。
数据范围: 1 ≤ k ≤ 1 0 9 1 ≤ k ≤ 10^9 1≤k≤109。
solution
首先我们二分答案 λ \lambda λ,把问题转化成求 [ 1 , λ ] [1,\lambda] [1,λ] 中不含平方因子的数的数量。
考虑这好像不太好求,我们不如求 [ 1 , λ ] [1,\lambda] [1,λ] 中含平方因子的数的个数,最后用 λ \lambda λ 减一减就可以了。
用容斥求这个东西,答案应该是:
a n s = ∑ i = 1 λ f ( i ) ⌊ λ i 2 ⌋ ans=\sum_{i=1}^{\sqrt\lambda}f(i)\lfloor\frac{\lambda}{i^2}\rfloor ans=i=1∑λf(i)⌊i2λ⌋
其中 f ( i ) f(i) f(i) 表示容斥系数,而 ⌊ λ i 2 ⌋ \lfloor \frac{\lambda}{i^2}\rfloor ⌊i2λ⌋ 表示 λ \lambda λ 中 i 2 i^2 i2 倍数的数的个数,那么:
f ( i ) = { 0 , i 有 平 方 因 子 − 1 , i 无 平 方 因 子 且 i 有 奇 数 个 质 因 数 1 , i 无 平 方 因 子 且 i 有 偶 数 个 质 因 数 f(i)=\begin{cases} 0,&i\,有平方因子\\ -1,&i\,无平方因子且\,i\,有奇数个质因数\\ 1,&i\,无平方因子且\,i\,有偶数个质因数 \end{cases} f(i)=⎩⎪⎨⎪⎧0,−1,1,i有平方因子i无平方因子且i有奇数个质因数i无平方因子且i有偶数个质因数
其实也就是 − - − 有 1 1 1 个质因数平方的 + + + 有 2 2 2 个质因数平方的 − - − 有 3 3 3 个质因数平方的 ⋯ \cdots ⋯。
发现 f ( i ) = μ ( i ) f(i)=\mu(i) f(i)=μ(i),那么直接线筛 μ \mu μ 然后计算即可。
时间复杂度 O ( n log n ) O(\sqrt n\log n) O(nlogn)。
code
#include<bits/stdc++.h>
#define N 50005
using namespace std;
int n,sum,prime[N],mark[N],mu[N];
void linear_sieves(){
mu[1]=1;
for(int i=2;i<N;++i){
if(!mark[i]) prime[++sum]=i,mu[i]=-1;
for(int j=1;j<=sum&&i*prime[j]<N;++j){
mark[i*prime[j]]=1;
if(i%prime[j]) mu[i*prime[j]]=-mu[i];
else {mu[i*prime[j]]=0;break;}
}
}
}
bool check(int mid){
int num=0;
for(int i=1;i*i<=mid;++i) num+=mu[i]*(mid/(i*i));
return num>=n;
}
int main(){
int T;
scanf("%d",&T);
linear_sieves();
while(T--){
scanf("%d",&n);
int l=1,r=n<<1;
while(l<r){
int mid=(1ll*l+r)>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
printf("%d\n",l);
}
return 0;
}