POJ_3468_Interval Tree 更新区间经典
--
/* POJ_3468_Interval Tree 更新区间 与 h1698 类似,但是你要清楚他们的区别 -- 为负,随时查询任意一个区间,上下面 Author : a_clay Created : 2012-02-04 */ #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #define get_mid(x) ((x) >> 1) using namespace std; const int N = 100005; struct node { int a, b; long long sum; long long kind; }t[3*N]; int n, m; int r[N]; long long SUM; void make_tree(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 { make_tree(x, get_mid(x+y), 2*num); make_tree(get_mid(x+y)+1, y, 2*num+1); t[num].sum = t[2*num].sum + t[2*num+1].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 = get_mid(t[num].a + t[num].b); if (x <= mid) { add(x, y, z, 2*num); } if (y > mid) { add(x, y, z, 2*num+1); } t[num].sum = t[2*num].sum + t[2*num+1].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 = get_mid(t[num].a + t[num].b); if (x <= mid) { query(x, y, 2*num); } if (y > mid) { query(x, y, 2*num+1); } } } int main() { int i; memset(t, 0, sizeof(t)); scanf("%d%d", &n, &m); for (i = 1; i <= n; i++) { scanf("%d", &r[i]); } make_tree(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; } } system("pause"); return 0; }