线段树 : 区间更新 poj 3468 示例

来源:互联网 发布:城乡发展不平衡数据 编辑:程序博客网 时间:2024/04/30 00:35
#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[N];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;}