标记永久化线段树 区间更新求和
#include <iostream> #include <cstdio> #include <cstring> using namespace std; typedef long long ll; const int MAXN = 100009; int n, q; ll sum[MAXN * 4], add[MAXN * 4]; void build(int l, int r, int rt) { add[rt] = 0; if (l == r) { scanf("%lld", &sum[rt]); return; } int mid = (l + r) >> 1; build(l, mid, rt << 1); build(mid + 1, r, rt << 1 | 1); sum[rt] = (sum[rt << 1] + sum[rt << 1 | 1]); } void update(int l, int r, int rt, int ql, int qr, int c) { sum[rt] += c * (qr - ql + 1); if (l == ql && r == qr) { add[rt] += c; return; } int mid = (l + r) >> 1; if (qr <= mid) update(l, mid, rt << 1, ql, qr, c); else if (ql > mid) update(mid + 1, r, rt << 1 | 1, ql, qr, c); else { update(l, mid, rt << 1, ql, mid, c); update(mid + 1, r, rt << 1 | 1, mid + 1, qr, c); } } ll query(int l, int r, int rt, int ql, int qr, ll c) { if (l == ql && r == qr) return sum[rt] + c * (r - l + 1); int mid = (l + r) >> 1; if (qr <= mid) return query(l, mid, rt << 1, ql, qr, c + add[rt]); else if (ql > mid) return query(mid + 1, r, rt << 1 | 1, ql, qr, c + add[rt]); else return query(l, mid, rt << 1, ql, mid, c + add[rt]) + query(mid + 1, r, rt << 1 | 1, mid + 1, qr, c + add[rt]); } int main() { scanf("%d %d", &n, &q); build(1, n, 1); char ch[2]; int x, y, z; while (q--) { scanf("%s", ch); if (ch[0] == 'Q') { scanf("%d %d", &x, &y); printf("%lld\n", query(1, n, 1, x, y, 0)); } else { scanf("%d %d %d", &x, &y, &z); update(1, n, 1, x, y, z); } } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
2017-04-10 sgu 131 状压DP