数列递推(牛客练习赛83)(数学、分块)
生活随笔
收集整理的這篇文章主要介紹了
数列递推(牛客练习赛83)(数学、分块)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
數列遞推
給定f(0)f(0)f(0),定義fn=∑i=1nf(nmodi)f_n = \sum\limits_{i = 1} ^{n} f_{(n \mod i)}fn?=i=1∑n?f(nmodi)?,求f1,f2,f3,…,fn?1,fnf_1, f_2, f_3, \dots, f_{n - 1}, f_{n}f1?,f2?,f3?,…,fn?1?,fn?。
∑i=1nf(nmodi)∑i=1nf(n?nii)\sum_{i = 1} ^{n} f_{(n \mod i)}\\ \sum_{i = 1} ^{n} f_{(n - \frac{n}{i} i)}\\ i=1∑n?f(nmodi)?i=1∑n?f(n?in?i)?
顯然ni\frac{n}{i}in?具有分塊性質,當ni\frac{n}{i}in?大于n\sqrt nn?時,iii只有n\sqrt nn?個選擇,可以直接枚舉,
否則ni<n\frac{n}{i} < \sqrt nin?<n?時,可以考慮Si,j=fi+fi?j+…S_{i, j} = f_i + f_{i - j} + \dotsSi,j?=fi?+fi?j?+…一個前綴和來轉移。
#include <bits/stdc++.h>using namespace std;const int N = 1e5 + 10, mod = 998244353;int f[N], s[N][310], 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; }int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);scanf("%d %d", &n, &f[0]);for (int i = 1; i < 310; i++) {s[0][i] = f[0];}for (int i = 1; i <= n; i++) {for (int l = 1, r, k; l <= i; l = r + 1) {r = i / (i / l), k = i / l;if (k < 310) {int L = i - k * r, R = i - k * l;f[i] = add(f[i], s[R][k]);if (L > k) {f[i] = sub(f[i], s[L - k][k]);}}else {for (int j = l; j <= r; j++) {f[i] = add(f[i], f[i - k * j]);}}}for (int j = 1; j < 310; j++) {if (i >= j) {s[i][j] = add(s[i - j][j], f[i]);}else {s[i][j] = f[i];}}}for (int i = 1; i <= n; i++) {printf("%d%c", f[i], i == n ? '\n' : ' ');}return 0; }總結
以上是生活随笔為你收集整理的数列递推(牛客练习赛83)(数学、分块)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C. Safe Distance(二分
- 下一篇: mrl什么意思