P4318 完全平方数
题意:
- 求第 k k k 个既不是完全平方数也不是完全平方正整数倍的数
分析:
-
对于 1 1 1 个完全平方数 a a a 和它的倍数,将其表示成质因子的幂次的乘积形式: a = 2 x 1 ∗ 3 x 2 ∗ 5 x 3 ∗ . . . a=2^{x_1}* 3^{x_2}*5^{x_3} * ... a=2x1∗3x2∗5x3∗... 那么必然存在 1 1 1 个质因子的幂次 > 1 >1 >1
反过来讲,我们要求的即第 k k k 个所有质因子的指数都为 1 1 1 的数(是不是有点熟悉,想一想莫比乌斯函数)
-
转换问题:求 [ 1 , x ] [1,x] [1,x] 满足条件的数的个数
考虑容斥,用筛法,将 2 2 , 3 2 , 5 2 , 7 2 . . . 2^2,3^2,5^2,7^2... 22,32,52,72... 和它们的倍数筛掉(类似埃氏筛法)
埃氏筛会重复筛掉一些数,对于 2 3 2^3 23 和 3 2 3^2 32 的倍数来说,筛了一遍 6 2 6^2 62 的倍数,因此还要加上 6 2 6^2 62 的倍数
往下考虑一下,即质因子个数为奇数的筛掉,为偶数的加回来
a n s = x + ( − 1 ) i 质 因 子 的 个 数 ∗ ( x / i / i ) ans = x+(-1)^{i质因子的个数}*(x/i/i) ans=x+(−1)i质因子的个数∗(x/i/i)
( x / i / i ) (x/i/i) (x/i/i) 的系数即莫比乌斯函数
a n s = ∑ i = 1 x m u ( i ) [ x i 2 ] ans = \sum_{i=1}^{\sqrt x}mu(i)[\frac{x}{i^2}] ans=∑i=1xmu(i)[i2x]
然后再用二分判断 [ k , 2 k ] [k,2k] [k,2k] 找到第一个大于 a n s > = k ans>=k ans>=k 的 x x x 即可
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int mu[N], b[N], pri[N];
void mus(int n)
{
int tot=0;
mu[1] = 1;
for(int i=2;i<n;i++)
{
if(!b[i]) mu[i] = -1, pri[++tot] = i;
for(int j=1;j<=tot && i*pri[j]<n;j++)
{
b[i*pri[j]] = 1;
if(i%pri[j]==0) break ;
mu[i*pri[j]] = -mu[i];
}
}
}
bool check(int k,int n)
{
int ans=0;
for(int i=1;i*i<=k;i++)
{
ans += mu[i]*(k/i/i);
}
return ans >= n;
}
signed main()
{
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
mus(4e4);
//for(int i=1;i<=100;i++) check(i,1), cout<<i<<' '<<endl;
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
int l=n, r=2*n;
int ans;
while(l<=r)
{
int mid = l+r>>1;
if(check(mid, n)) r = mid-1;
else l = mid+1;
}
cout<<l<<endl;
}
return 0;
}