线段树 : 区间更新 poj 3468 示例
2013-01-16 21:25
525 查看
#include <iostream> #include <string> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <vector> #include <stack> #include <deque> #include <queue> #include <bitset> #include <list> #include <map> #include <set> #include <iterator> #include <algorithm> #include <functional> #include <utility> #include <sstream> #include <climits> #include <cassert> #define BUG puts("here!!!"); #define MID(x) (x) >> 1 #define L(x) (x) << 1 #define R(x) ((x) << 1 | 1) using namespace std; const int N = 100005; struct Node { int a, b; long long sum; long long kind; }t[4*N]; int n, m; int r ; long long SUM; void makeTree(int x, int y, int num) { t[num].a = x; t[num].b = y; t[num].kind = 0; if(x == y) t[num].sum = r[y]; else { int mid = MID(x+y); makeTree(x, mid, L(num)); makeTree(mid+1, y, R(num)); t[num].sum = t[L(num)].sum + t[R(num)].sum; } } void add(int x, int y, int z, int num) { if(x <= t[num].a && t[num].b <= y) { // 找终止节点 t[num].sum += (t[num].b - t[num].a + 1) * z; t[num].kind += z; } else { if(t[num].kind != 0) { t[2*num].kind += t[num].kind; t[2*num+1].kind += t[num].kind; t[2*num].sum += (t[2*num].b - t[2*num].a + 1) * t[num].kind; t[2*num+1].sum += (t[2*num+1].b - t[2*num+1].a + 1) * t[num].kind; t[num].kind = 0; } int mid = MID(t[num].a + t[num].b); if(x <= mid) add(x, y, z, L(num)); if(y > mid) add(x, y, z, R(num)); t[num].sum = t[L(num)].sum + t[R(num)].sum; } } void query(int x, int y, int num) { if(x <= t[num].a && t[num].b <= y) { SUM += t[num].sum; } else { if(t[num].kind != 0) { t[2*num].kind += t[num].kind; t[2*num+1].kind += t[num].kind; t[2*num].sum += (t[2*num].b - t[2*num].a + 1) * t[num].kind; t[2*num+1].sum += (t[2*num+1].b - t[2*num+1].a + 1) * t[num].kind; t[num].kind = 0; } int mid = MID(t[num].a + t[num].b); if(x <= mid) query(x, y, L(num)); if(y > mid) query(x, y, R(num)); t[num].sum = t[L(num)].sum + t[R(num)].sum; } } int main() { int i; scanf("%d%d", &n, &m); for(i = 1; i <= n; i++) { scanf("%d", &r[i]); } makeTree(1, n, 1); while(m--) { int a, b, c; char str[3]; scanf("%s", str); if(str[0] == 'C') { scanf("%d%d%d", &a, &b, &c); add(a, b, c, 1); } else { scanf("%d%d", &a, &b); SUM = 0; query(a, b, 1); cout << SUM << endl; } } return 0; }
相关文章推荐
- 线段树 : 区间更新 poj 3468 示例
- 线段树 : 区间更新 poj 3468 示例
- (Relax 线段树1.1)POJ 3468 A Simple Problem with Integers(线段树子区间更新的维护:集中更新和动态统计子序列中的数据)
- POJ-3468(线段树区间更新区间查询)
- 线段树区间更新(以POJ 3468为例)
- POJ 3468 A Simple Problem with Integers (线段树区间更新模板题)
- 【POJ】3468 (线段树,区间成段按需更新)
- POJ 3468 A Simple Problem with Integers 【线段树,区间更新】
- POJ 3468 A Simple Problem with Integers 线段树区间更新 (值在基础上相加或相减)
- poj 3468 A Simple Problem with Integers(线段树——区间更新)
- poj 3468 线段树区间更新lazy
- POJ 3468 线段树 区间更新区间查询
- POJ 3468 A Simple Problem with Integers (线段树区间更新经典)
- POJ 3468 A Simple Problem with Integers (线段树区间更新模板)
- poj 3468 A Simple Problem with Integers (线段树区间更新求和lazy思想)
- POJ 3468 线段树区间更新求和模板
- poj 3468 (线段树区间更新及求和)
- 线段树 + 区间更新 + 模板 ---- poj 3468
- poj 3468 A Simple Problem with Integers 线段树区间更新
- POJ 3468 线段树(区间更新)