poj 3467(线段树成段更新)

来源:互联网 发布:长江证券交易软件下载 编辑:程序博客网 时间:2024/06/12 18:13

题目链接:点击打开链接


题意: 略


分析: 可设一另设两个域sum 和d分别表示该区间的当前和与该区间的每个元素的增量,之后维护线段树即可! 再次感慨代码能力、、、、


#include <iostream>using namespace std;__int64 sum1;int a[100005];struct node{int left, right;int d;__int64 sum;}tree[1000000];void creat (int root, int left, int right){tree[root].left = left;tree[root].right = right;tree[root].sum = 0;tree[root].d = 0;if (left == right){tree[root].sum = a[left];return;}   int mid = (left+right)/2;    creat(2*root, left,mid);creat(2*root+1, mid+1, right);tree[root].sum = tree[2*root].sum + tree[2*root+1].sum;}void insert (int root, int left, int right, int x){    if (tree[root].left == left && tree[root].right == right){tree[root].d += x;return;}    tree[root].sum += x*(right -left+1);int mid = (tree[root].left+ tree[root].right)/2;    if (left > mid)insert(2*root+1,left, right, x);else if (right <= mid)insert(2*root, left, right, x);else {insert(2*root,left, mid, x);insert(2*root+1, mid+1,right,x);}}void search(int root, int left, int right){    if (tree[root].left == left && tree[root].right == right){   sum1 += (tree[root].sum + (__int64)tree[root].d*(right-left+1));    return;}if (tree[root].d){tree[root].sum +=(__int64)tree[root].d*(tree[root].right-tree[root].left+1);tree[2*root].d += tree[root].d;tree[2*root+1].d += tree[root].d;tree[root].d = 0;}int mid = (tree[root].left + tree[root].right)/2;if (left > mid)search(2*root+1, left, right);else if (right <= mid)search(2*root,left, right);else {search(2*root, left, mid);search(2*root+1, mid+1, right);}}void print(int root){if (tree[root].left == tree[root].right){printf ("%d %d %I64d\n",tree[root].left , tree[root].right , tree[root].sum);return ;}printf ("%d %d %I64d\n", tree[root].left , tree[root].right  , tree[root].sum);print(2*root);print(2*root+1);}int main (){int n, m, t, i, l, r;int x;char ch;    scanf ("%d%d", &n, &m);for(i = 1; i <= n; i++)scanf("%d", &a[i]);creat (1,1, n);//print(1);for (i = 0; i < m; i++){getchar();scanf("%c",&ch);if (ch == 'C'){scanf("%d%d%d", &l, &r, &x);if (l > r){t = l;l = r;r = t;}insert (1, l, r, x);}else {scanf("%d%d", &l, &r);if (l > r){t = l;l = r;r = t;}sum1  = 0;search(1, l, r);printf ("%I64d\n",sum1);}}return 0;}