线段树模板
2017-08-19 09:26
441 查看
#include <iostream> #include <cstdlib> #include <cstdio> #define maxn 100005 #define mid (l+r)/2 using namespace std; int n, m; long long sum[maxn << 2], maxs[maxn << 2], add[maxn<<2]; void PushUp(int id) { sum[id] = sum[id << 1] + sum[id << 1 | 1]; maxs[id] = max(maxs[id << 1], maxs[id << 1 | 1]); } void Pusdown(int pr, int pl, int id) { if(add[id]) { add[id << 1] += add[id]; add[id << 1 | 1] += add[id]; sum[id << 1] += add[id] * pr; sum[id << 1 | 1] += add[id] * pl; maxs[id << 1] += add[id]; maxs[id << 1 | 1] += add[id]; add[id] = 0; } } void Build(int l, int r, int id) //建树 { add[id] = 0; if(l == r) { scanf("%lld", &sum[id]); maxs[id] = sum[id]; return ; } Build(l, mid, id << 1); Build(mid + 1, r, id << 1 | 1); PushUp(id); } void Update(int l, int r, int id, int pos, long long c) //点修改 { if(l > pos || r < pos) return ; if(l == r && l == id) { sum[id] += c; maxs[id] += c; return ; } Update(l, mid, id << 1, pos, c); Update(mid + 1, r, id << 1 | 1, pos, c); PushUp(id); } void UpDate(int l, int r, int pl, int pr, int id, long long c) //区间修改 { if(l > pr || r < pl) return ; if(l >= pl && r <= pr) { sum[id] += (r - l + 1) * c; maxs[id] += c; add[id] += c; return; } Pusdown(mid - l + 1, r - mid,id); UpDate(l, mid, pl, pr, id << 1, c); UpDate(mid + 1, r, pl, pr, id << 1 | 1, c); PushUp(id); } long long Query(int l, int r, int pl, int pr, int id) { if(r < pl || l > pr) return 0; if(l >= pl && r <= pr) { return sum[id]; } Pusdown(mid - l + 1, r - mid, id); long long sums = 0; sums += Query(l, mid, pl, pr, id << 1); sums += Query(mid + 1, r, pl, pr, id << 1 | 1); return sums; } long long QueryMax(int l, int r, int pl, int pr, int id) { if(r < pl || l > pr) return 0; if(l >= pl && r <= pr) { return maxs[id]; } Pusdown(mid - l + 1, r - mid, id); long long ma = 0; ma = max(Query(l, mid, pl, pr, id << 1), Query(mid + 1, r, pl, pr, id << 1 | 1)); return ma; } int main() { char c; int x, y; long long d; scanf("%d %d", &n, &m); Build(1, n, 1); getchar(); while(m--) { scanf("%c", &c); if(c == 'Q') { scanf("%d %d", &x, &y); cout << Query(1, n, x, y, 1) << endl; } else { scanf("%d %d %lld", &x, &y, &d); UpDate(1, n, x, y, 1, d); } getchar(); } return 0; }
相关文章推荐
- 线段树维护区间和模板(单结点更新)(1166)
- hdu 1166 线段树 单点修改 + 询问区间求和 (线段树模板)
- P3372 【模板】线段树 1
- HDU 1166 树状数组&&线段树模板1
- hdu1698(线段树区间替换模板)
- BZoj 1036: [ZJOI2008]树的统计Count【树链剖分+线段树--模板题】
- 线段树入门(个人习惯模板)--士兵杀敌
- 线段树模板
- LA 2191电位计(线段树模板题)
- 线段树模板整理
- NEFU 1215 统计序列和 (线段树模板题)
- poj3468 线段树成段更新模板
- 线段树模板
- 【线段树】线段树模板 胡浩版
- 线段树模板
- HDU1754 I Hate it 线段树模板题
- 各种树模板(splay,线段树,可持久化线段树...)
- 线段树模板
- POJ 3468 线段树区间更新求和模板
- NOIP算法每周过之 线段树 区间 区间修改 区间查值 模板