luogu P4318 完全平方数
今天膜你赛的时候我想推一个 \(\sum\limits_{i=1}^n \mu^2(i)\),结果太弱智了没推出来,然后就来看了这道题。
首先考虑二分答案。现在问题就转化为如何求上述式子。
对每个质因子的平方进行容斥,发现对于每个数容斥系数恰好是 \(u(i)\)。所以原式即为 \(\sum\limits_{i=1}^{\lfloor\sqrt n \rfloor}\mu(i)\lfloor \frac{n}{i^2}\rfloor\)。时间复杂度 \(O(\sqrt n+TlogK)\)。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define int long long
using namespace std;
const int N = 100000;
int k, a[N + 9], p[N], cnt, u[N + 9];
void prework()
{
u[1] = 1;
for (int i = 2; i <= N; i++)
{
if (!a[i])
a[i] = i, p[++cnt] = i, u[i] = -1;
for (int j = 1; j <= cnt; j++)
{
if (p[j] > a[i] || p[j] > N / i)
break;
a[p[j] * i] = p[j];
if (i % p[j])
u[p[j] * i] = u[p[j]] * u[i];
}
}
}
void init()
{
scanf("%lld", &k);
}
int check(int n)
{
int res = 0;
for (int i = 1; i * i <= n; i++)
res += u[i] * (n / (i * i));
return res;
}
void work()
{
int l = 1, r = 2e10, mid;
while (l <= r)
{
mid = l + r >> 1;
if (check(mid) < k)
l = mid + 1;
else
r = mid - 1;
}
printf("%lld\n", l);
}
signed main()
{
prework();
int T;
scanf("%lld", &T);
while (T--)
init(),
work();
return 0;
}
由于博主比较菜,所以有很多东西待学习,大部分文章会持续更新,另外如果有出错或者不周之处,欢迎大家在评论中指出!