YACS 2022年12月月赛 甲组 T1 分割序列 题解
这题是 子串的平均数 的进阶版,建议先去做子串的平均数再来做这一题。
暴力
先考虑
那么枚举这一组怎么分,就可以了。
状态转移方程:
代码:
#include <iostream> using namespace std; int n; int a[200005], f[200005]; long long sum; int main () { cin >> n; for (int i = 1; i <= n; i ++) cin >> a[i]; f[0] = 1; for (int i = 1; i <= n; i ++) { long long sum = 0; for (int j = i; j >= 1; j --) { sum += a[j]; if (sum >= 0) f[i] = (f[i] + f[j - 1]) % 10000007; } } cout << f[n] << "\n"; return 0; }
优化
这个东西一看就知道可以用动态开点权值线段树来优化,算出了
最终时间复杂度:
代码(欣赏一下我的线段树码风):
#include <iostream> #define int long long using namespace std; int n, x, y = 1, sum = 1, mod = 1000000007; int a[200010], f[200010], tree[8000010], ls[8000010], rs[8000010]; void add (int l, int r, int k) { tree[k] = (tree[k] + y) % mod; if (l == r) return; int mid = l + r >> 1; if (x <= mid) { if (!ls[k]) ls[k] = ++ sum; add (l, mid, ls[k]); } else { if (!rs[k]) rs[k] = ++ sum; add (mid + 1, r, rs[k]); } } int query (int l, int r, int k) { if (x <= l && y >= r) return tree[k]; int mid = l + r >> 1, res = 0; if (x <= mid) res += query (l, mid, ls[k]); if (y > mid) res = (res + query (mid + 1, r, rs[k]) ) % mod; return res; } signed main () { cin >> n; for (int i = 1; i <= n; i ++) { cin >> a[i]; a[i] += a[i - 1]; } f[0] = 1; for (int i = 0; i <= n; i ++) { if (i == 0) add (-200000000000, 200000000000, 1); else { x = -200000000000; y = a[i]; f[i] = query (-200000000000, 200000000000, 1); x = a[i]; y = f[i]; add (-200000000000, 200000000000, 1); } } cout << f[n]; return 0; }
分类:
YACS甲组月赛题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异