前言
刚刚学习了莫比乌斯函数和性质一:
性质一:
[sum_{d|n} mu(d) = [n=1]
]
([n=1])表示(n=1)返回(1),否则返回(0)
证明
当(n>1)时
设(omega(n))表示(n)的不同质因子的个数
[egin{aligned}
sum_{d|n} mu(d) &= sum_{i=0}^{omega(n)} inom{omega(n)}{i} (-1)^i \
&=sum_{i=0}^{omega(n)} inom{omega(n)}{i} (-1)^i * 1^{omega(n)-i} \
end{aligned}
]
看到这个就会想到二次式定理:
[(a+b)^n = sum_{i=0}^n inom{n}{i} a^i b^{n-i}
]
根据二次式定理
可以继续化简
[egin{aligned}
&=(-1+1)^{omega(n)} \
&=0 \
end{aligned}
]
当(n=1)时
不用说(mu(1)=1)
证毕
进入正题
题目大意:(N)组数据,求第(k)大的不是完全平方数的倍数的数
设(x)为不是完全平方数的倍数的数
则(mu ^2 (x)=1)
设
[f(i)=max_{d^2|i} d
]
那么当(f(i)=1)时,(i)就为不是完全平方数的倍数的数
则从(1)到(n)的不是完全平方数的倍数的数的个数为
[sum_{i=1}^n [f(i)=1]
]
带入性质一
[egin{aligned}
&= sum_{i=1}^n sum_{d|f(i)} mu(d) \
&= sum_{i=1}^n sum_{d^2|i} mu(d) \
&= sum_{d=1} sum_{d^2|i} mu(d) \
&= sum_{d=1} mu(d) sum_{d^2|i} 1 \
&= sum_{d=1} mu(d) lfloor frac{n}{d^2}
floor \
end{aligned}
]
结束
(mu)的值可以用筛法求出
时间复杂度为(O(sqrt n log n))
代码:
#include<cstdio>
#define ll long long
using namespace std;
int mo[400000],p[400000],tot=0,n;
bool vis[400000];
void init()
{
mo[1]=1;
for (int i=2;i<=320000;i++)
{
if (!vis[i]) p[++tot]=i,mo[i]=-1;
for (int j=1;j<=tot&&p[j]*i<=320000;j++)
{
vis[p[j]*i]=true;
if (i%p[j]==0) break;
mo[p[j]*i]=-mo[i];
}
}
}
bool check(ll x)
{
ll res=0;
for (int i=1;i*i<=x;i++)
res+=mo[i]*(x/(i*i));
return res>=n;
}
int main()
{
init();
int t;
scanf("%d",&t);
while (t--)
{
scanf("%d",&n);
ll l=n,r=n<<1;
while (l<r)
{
ll mid=(l+r)>>1;
if (check(mid)) r=mid;
else l=mid+1;
}
printf("%lld
",r);
}
}