E. Mocha and Stars
∑a1=l1r1∑a2=l2r2⋯∑an=lnrn[a1+a2+⋯+an≤m][gcd(a1,a2,…,an)=1]\sum_{a_1 = l_1} ^{r_1} \sum_{a_2 = l_2} ^{r_2} \dots \sum_{a_n = l_n} ^{r_n} [a_1 + a_2 + \dots + a_n \le m][\gcd(a_1, a_2, \dots, a_n) = 1]\\ a1=l1∑r1a2=l2∑r2⋯an=ln∑rn[a1+a2+⋯+an≤m][gcd(a1,a2,…,an)=1]
有2≤n≤50,1≤m≤105,1≤li≤ri≤m2 \le n \le 50, 1 \le m \le 10 ^ 5, 1 \le l_i \le r_i \le m2≤n≤50,1≤m≤105,1≤li≤ri≤m,对上述答案对998244353998\ 244\ 353998 244 353取模。
∑a1=l1r1∑a2=l2r2⋯∑an=lnrn[a1+a2+⋯+an≤m][gcd(a1,a2,…,an)=1]∑k=1mμ(k)∑a1=⌈l1k⌉⌊r1k⌋∑a2=⌈l2k⌉⌊r2k⌋⋯∑an=⌈lnk⌉⌊rnk⌋[a1+a2+⋯+an≤⌊md⌋]\sum_{a_1 = l_1} ^{r_1} \sum_{a_2 = l_2} ^{r_2} \dots \sum_{a_n = l_n} ^{r_n} [a_1 + a_2 + \dots + a_n \le m][\gcd(a_1, a_2, \dots, a_n) = 1]\\ \sum_{k = 1} ^{m} \mu(k) \sum_{a_1 = \lceil \frac{l_1}{k} \rceil} ^{\lfloor \frac{r_1}{k} \rfloor} \sum_{a_2 = \lceil \frac{l_2}{k} \rceil} ^{\lfloor \frac{r_2}{k} \rfloor} \dots \sum_{a_n = \lceil \frac{l_n}{k} \rceil} ^{\lfloor \frac{r_n}{k} \rfloor} [a_1 + a_2 + \dots + a_n \le \lfloor \frac{m}{d} \rfloor]\\ a1=l1∑r1a2=l2∑r2⋯an=ln∑rn[a1+a2+⋯+an≤m][gcd(a1,a2,…,an)=1]k=1∑mμ(k)a1=⌈kl1⌉∑⌊kr1⌋a2=⌈kl2⌉∑⌊kr2⌋⋯an=⌈kln⌉∑⌊krn⌋[a1+a2+⋯+an≤⌊dm⌋]
其中∑a1=⌈l1k⌉⌊r1k⌋∑a2=⌈l2k⌉⌊r2k⌋⋯∑an=⌈lnk⌉⌊rnk⌋[a1+a2+⋯+an≤⌊md⌋]\sum\limits_{a_1 = \lceil \frac{l_1}{k} \rceil} ^{\lfloor \frac{r_1}{k} \rfloor} \sum\limits_{a_2 = \lceil \frac{l_2}{k} \rceil} ^{\lfloor \frac{r_2}{k} \rfloor} \dots \sum\limits_{a_n = \lceil \frac{l_n}{k} \rceil} ^{\lfloor \frac{r_n}{k} \rfloor} [a_1 + a_2 + \dots + a_n \le \lfloor \frac{m}{d} \rfloor]a1=⌈kl1⌉∑⌊kr1⌋a2=⌈kl2⌉∑⌊kr2⌋⋯an=⌈kln⌉∑⌊krn⌋[a1+a2+⋯+an≤⌊dm⌋],可以考虑dpdpdp求解,f[i][j]f[i][j]f[i][j],表示前iii个数,和为jjj的方案有多少,复杂度n×⌊md⌋n \times \lfloor \frac{m}{d} \rfloorn×⌊dm⌋。
由此,整体复杂度是n×m×logmn \times m \times \log mn×m×logm。
#include <bits/stdc++.h>using namespace std;const int N = 1e5 + 10, mod = 998244353;int mu[N], prime[N], L[N], R[N], f[N], pre[N], n, cnt, M;bool st[N];inline int add(int x, int y) {return x + y < mod ? x + y : x + y - mod;
}inline int sub(int x, int y) {return x >= y ? x - y : x - y + mod;
}void init() {mu[1] = 1;for (int i = 2; i < N; i++) {if (!st[i]) {prime[++cnt] = i;mu[i] = -1;}for (int j = 1; j <= cnt && 1ll * i * prime[j] < N; j++) {st[i * prime[j]] = 1;if (i % prime[j] == 0) {break;}mu[i * prime[j]] = -mu[i];}}
}int F(int d) {int m = M / d, sum = 0;for (int i = 1; i <= n; i++) {int l = (L[i] + d - 1) / d, r = R[i] / d;if (l > r) {return 0;}sum += l;}if (sum > m) {return 0;}for (int i = 1; i <= m; i++) {f[i] = 0;}for (int i = 1; i <= n; i++) {int l = (L[i] + d - 1) / d, r = R[i] / d;if (i == 1) {for (int j = l; j <= r; j++) {f[j] = 1;}continue;}for (int j = 1; j <= m; j++) {pre[j] = add(pre[j - 1], f[j]);f[j] = 0;}for (int j = 1; j <= m; j++) {// x + {l, l + 1, ………, r} = j, x = [j - r, j - l]int L = max(1, j - r), R = j - l;if (L > R) {continue;}f[j] = sub(pre[R], pre[L - 1]);}}int ans = 0;for (int i = 1; i <= m; i++) {ans = add(ans, f[i]);}return ans;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);init();scanf("%d %d", &n, &M);for (int i = 1; i <= n; i++) {scanf("%d %d", &L[i], &R[i]);}int ans = 0;for (int i = 1; i <= M; i++) {if (mu[i] == -1) {ans = sub(ans, F(i));}else if (mu[i] == 1) {ans = add(ans, F(i));}}printf("%d\n", ans);return 0;
}