专栏文章
题解:P10663 BZOJ4833 最小公倍佩尔数
P10663题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minl2s2o
- 此快照首次捕获于
- 2025/12/02 04:10 3 个月前
- 此快照最后确认于
- 2025/12/02 04:10 3 个月前
首先知道 。证明同
fib 的情况。 好求,问 ,考虑 容斥,.
枚举 ,设为 。考虑每个 对答案的贡献。首先里面有个 。观察到 ,再把空集去掉得到 。
对于 为 的集合 ,设 ,有 。扫描 的时候, 在后面会接上一个 ,因此 会加上 。直接求即可。
CPP#include <bits/stdc++.h>
using namespace std;
#define N 5000005
#define int long long
int e[N], f[N], d[N], mu[N], I[N], prm[N], n, p, T, cur, ans;
int pw(int a, int t) {
if (!t)
return 1;
int x = pw(a, t >> 1);
x = x * x % p;
if (t & 1)
x = x * a % p;
return x;
}
void solve() {
e[0] = 1, cin >> n >> p, cur = 1, ans = 0;
for (int i = 1; i <= n; i++)
f[i] = (e[i - 1] + f[i - 1]) % p, e[i] = (e[i - 1] + f[i - 1] * 2) % p, I[i] = pw(f[i], p - 2), d[i] = 1;
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j += i)
d[j] = d[j] * (mu[j / i] ? ((~mu[j / i]) ? f[i] : I[i]) : 1) % p;
for (int i = 1; i <= n; i++)
cur = cur * d[i] % p, ans = (ans + i * cur) % p;
cout << ans << '\n';
}
main() {
for (int i = 1; i < N; i++)
mu[i] = 1;
for (int i = 2; i < N; i++)
if (!prm[i]) {
for (int j = i; j < N; j += i)
prm[j] = 1, mu[j] = -mu[j];
for (int j = i * i; j < N; j += i * i)
mu[j] = 0;
}
cin >> T;
while (T--)
solve();
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...