题目
2440:[中山市选2011]完全平方数
TimeLimit:10Sec
MemoryLimit:128MB
Description
小 X 自幼就很喜欢数。但奇怪的是,他十分讨厌完全平方数。他觉得这些数看起来很令人难受。由此,他也讨厌所有是完全平方数的正整数倍的数。然而这丝毫不影响他对其他数的热爱。
这天是小X的生日,小 W 想送一个数给他作为生日礼物。当然他不能送一个小X讨厌的数。他列出了所有小X不讨厌的数,然后选取了第 K个数送给了小X。小X很开心地收下了。
然而现在小 W 却记不起送给小X的是哪个数了。你能帮他一下吗?
Input
包含多组测试数据。文件第一行有一个整数
T
,表示测试数据的组数。
第
Output
含
T
行,分别对每组数据作出回答。第
第
Ki
个不是完全平方数的正整数倍的数。
SampleInput
4
1
13
100
1234567
SampleOutput
1
19
163
2030745
HINT
对于100%的数据有1≤Ki≤109,T≤50
题解
莫比乌斯反演模板题
首先题面有误,完全平方数不包括1,不然就舒服了。
我们可以把问题转化为计算
[1,n]
中满足条件的数的个数。
这样我们就可以用二分答案求解这题。
但是我不会计算个数
联想到xxcc做过的小学奥数题
计算个数可以用容斥原理,
ans=n
-奇数个质数相乘的平方倍数的个数+偶数个质数相乘的平方倍数的个数。
非常的绕,但是非常不容易理解。
同时,这种类型的题,容斥系数恰好就是莫反函数。所以可以预处理线性筛莫反,然后计算时枚举素数计算。
总时间复杂度
O(TK−−√logK)
。
总结
模板题,不总结
xxcc说这是模板题,所以不总结
嗯……这题……就是……容斥……用莫反……来写……的……模板题……
标程
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=50005;
bool vis[N];
ll miu[N];
ll pri[N];
ll t, n, top;
void init()
{
miu[1]=1;
for (ll i=2; i<=50000; i++)
{
if (!vis[i])
{
pri[++top]=i;
miu[i]=-1;
}
for (ll j=1; j<=top; j++)
{
if (i*pri[j]>50000) break;
vis[i*pri[j]]=1;
if (i%pri[j]==0) break;
miu[i*pri[j]]=-miu[i];
}
}
}
ll calc(ll x)
{
ll sum=0;
for (ll i=1; i*i<=x; i++)
sum+=x/i/i*miu[i];
return sum;
}
void work()
{
scanf("%lld", &n);
ll l=n-1, r=2e9;
while (l+1<r)
{
ll mid=(l+r)>>1;
if (calc(mid)<n) l=mid;
else r=mid;
}
printf("%lld\n", r);
}
int main()
{
init();
scanf("%lld", &t);
while (t--) work();
return 0;
}
友情链接
bzoj2440解题报告
(大神比较喜欢黑色)
xxcc
大神解题报告
(就是那个王小花)
(就是那个很巨的王小花)
(就是那个叫我姐姐的王小花)
若有疑惑,问大神去。