题解 CF1559E
求出满足以下条件的整数数组
a 个数
- 长度为
n - 和不超过
m - 最大公约数是
1 a_i \in [l_i, r_i]
如果没有
主要的问题还是出在这个
主要是没有想到一个容斥的小 trick。
在处理
那么就可以用
用这个方法结合原来的背包,先用背包求出
但是赛场上我还是遇到了一个小问题改变了我思考的方向,在考虑容斥之前考虑求总数的时候觉得这个复杂度是
实际上这个复杂度根本就是
#include <iostream>
#include <algorithm>
#define int long long
const int N = 55, M = 100005, P = 998244353;
int n, m, l[N], r[N], f[N][M], ans[M];
signed main() {
std::cin >> n >> m;
for (int i = 1; i <= n; i++) std::cin >> l[i] >> r[i];
for (int g = m/n; g >= 1; g--) {
for (int i = 0; i <= n; i++)
for (int j = 0; j <= m/g+1; j++) f[i][j] = 0;
for (int j = 0; j <= m/g+1; j++) f[0][j] = 1;
for (int i = 1; i <= n; i++) {
int L = (l[i]+g-1)/g, R = r[i]/g;
for (int a = L; a <= m/g+1; a++) {
int cl = std::max(a-R, 0ll), cr = a-L;
if (cl > cr) f[i][a] = 0;
else f[i][a] = (f[i-1][cr] - (cl ? f[i-1][cl-1] : 0) + P) % P;
if (a > 0) f[i][a] = (f[i][a] + f[i][a-1]) % P;
}
}
ans[g] = f[n][m/g];
for (int i = 2*g; i <= m; i += g) ans[g] = (ans[g] - ans[i] + P) % P;
}
std::cout << ans[1];
}