欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

数列递推(牛客练习赛83)(数学、分块)

发布时间:2023/12/4 编程问答 37 豆豆
生活随笔 收集整理的这篇文章主要介绍了 数列递推(牛客练习赛83)(数学、分块) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

数列递推

给定f(0)f(0)f(0),定义fn=∑i=1nf(nmodi)f_n = \sum\limits_{i = 1} ^{n} f_{(n \mod i)}fn=i=1nf(nmodi),求f1,f2,f3,…,fn−1,fnf_1, f_2, f_3, \dots, f_{n - 1}, f_{n}f1,f2,f3,,fn1,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=1nf(nmodi)i=1nf(nini)

显然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+fij+一个前缀和来转移。

#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)(数学、分块)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。