大概题意
求出第k个所有因数指数为1的数字
比如 6=2*3 这就是一个因数指数都为1的数字
反之 9=3*3 3的指数为2 因此不满足要求
首先来看一看莫比乌斯函数
N=p11∗p12∗p13...p1k==>μ(N)=(−1)k
反之 若有任何一个
pi
的指数
>1
则
μ(N)=0
这样感觉就解决了我们的问题 所有的数字我们只统计 μ(N)!=0 的即可
但是这道题目的
k
过于大了
所以我们考虑反向求解
正确解法
对于一个数字
在枚举
<=N−−√
的 无完全平方数因子 的 只有一个质因数 的因子
i
根据它的指数为1的质因子的个数,求出 为它平方的数字的个数
如此一来 我们就把所有的完全平方数的倍数给删去了
但是!!我们好像多删了一些数字…
比如 3*3*16 和 4*4*9 我们分别讨论的是 3 和 4 的平方的倍数
但是不可避免地多删去了一次他们平方的公倍数
于是 我们用容斥定理来解决这个矛盾
每一次 我们删去 含且仅含奇数个质因数因子且无完全平方数因子 的因子的倍数
再加上 含且仅含偶数个质因数因子且无完全平方数因子 的因子的倍数
考虑到
μ(N)
的定义 对于满足第一个条件的
N=p11∗p12∗p13...p1k(kmod2==1)
其
μ(N)=1
而满足第二个条件的
N=p11∗p12∗p13...p1k(kmod2==0)
其
μ(N)=−1
因此最后的结果即为 res=∑⌊N√⌋k=1μ(k)∗⌊Nk2⌋
附上参考代码
#include <iostream>
#include <cstdio>
using namespace std;
int prime[50005],cnt=0,mu[50005];
bool mark[50005];
void MU()
{
mu[1]=1;
for(int i=2;i<=50000;i++)
{
if(!mark[i])prime[++cnt]=i,mu[i]=-1;
for(int j=1;j<=cnt&&prime[j]*i<=50000;j++)
{
mark[i*prime[j]]=1;
if(i%prime[j]==0){mu[i*prime[j]]=0;break;}
else mu[i*prime[j]]=-mu[i];
}
}
}
long long CAL(long long x)
{
long long res=0;
for(int i=1;i*i<=x;i++)
res+=mu[i]*x/(i*i);
return res;
}
int main()
{
// freopen("In.txt","r",stdin);
// freopen("Out.txt","w",stdout);
long long T,L,R,mid,k,ans;
MU();
scanf("%lld",&T);
while(T--)
{
scanf("%lld",&k);
L=k;R=1644934082;
while(L<R)
{
mid=L+R+1>>1;
if(CAL(mid)>=k)R=mid;
else L=mid+1;
}
printf("%lld\n",R);
}
}