POJ 3468 A Simple Problem with Integers 线段树

线段树

View Code
  1 /*
  2     poj3468
  3 */
  4 #include <iostream>
  5 using namespace std;
  6 const int N = 100005;
  7 
  8 struct node
  9 {
 10     int left, right;
 11     long long  num, add;
 12 }tree[4*N];
 13 
 14 int L(int n)
 15 {
 16     return n<<1;
 17 }
 18 int R (int n)
 19 {
 20     return (n<<1) | 1;
 21 }
 22 void update(int step)    //若当前节点的标志位add有值,则更新其左右节点
 23 {
 24     tree[L(step)].num += tree[step].add * (tree[L(step)].right - tree[L(step)].left + 1);
 25     tree[L(step)].add += tree[step].add;    //将标志位传给子节点
 26     tree[R(step)].num += tree[step].add * (tree[R(step)].right - tree[R(step)].left + 1);
 27     tree[R(step)].add += tree[step].add;
 28     tree[step].add = 0;                        //父节点清0
 29 }
 30 int a[N];
 31 
 32 void build(int l, int r, int step)    
 33 {
 34     tree[step].left = l;
 35     tree[step].right = r;
 36     tree[step].add = 0;
 37     if (l == r)        //到达叶子节点了
 38     {
 39         tree[step].num = a[l];
 40         return;
 41     }
 42     int mid = (l + r) >> 1;
 43     build(l, mid, L(step));
 44     build(mid+1, r, R(step));
 45     //其构造是自下而上(先求出其子节点的值),那么其父亲节点很明显就是其左右节点值的和
 46     tree[step].num = tree[L(step)].num + tree[R(step)].num;
 47 }
 48 
 49 void insert(int l, int r, int step, int add)
 50 {
 51     if (l<= tree[step].left && tree[step].right <= r)
 52     {
 53         tree[step].add += add;    
 54         tree[step].num += add * (tree[step].right - tree[step].left + 1);    //add * len
 55         return;
 56     }
 57     if (tree[step].add != 0)    //
 58     {
 59         update(step);
 60     }
 61     int mid = (tree[step].left + tree[step].right) >> 1;
 62     if (mid >= l) 
 63         insert(l, r, L(step), add);
 64     if (mid < r)
 65         insert(l, r, R(step), add);
 66     //由于可能其子节点有更新,我们需要在重新计算一次step这层的值
 67     tree[step].num = tree[L(step)].num + tree[R(step)].num;
 68 }
 69 
 70 long long  query(int l, int r, int step)
 71 {
 72     long long ans = 0;
 73     if (l <= tree[step].left && tree[step].right <= r)
 74     {
 75         return tree[step].num;
 76     }
 77     if (tree[step].add != 0)
 78     {
 79         update(step);
 80     }
 81     int mid = (tree[step].left + tree[step].right) >> 1;
 82     if (mid >= l)    //与左节点有交集
 83         ans += query(l, r, L(step));
 84     if (mid < r)    //与右节点有交集
 85         ans += query(l, r, R(step));
 86     return ans;
 87 }
 88 
 89 int main()
 90 {
 91     int  n, q, i, k, l, r, add;
 92     char str;
 93 
 94     scanf("%d%d", &n, &q);
 95     for (i=1; i<=n; i++)
 96         scanf("%d", &a[i]);
 97     build(1, n, 1);
 98     
 99     while (q--)
100     {
101         getchar();
102         scanf("%c", &str);
103     //    printf("----->%c\n",str);
104         if (str == 'Q')
105         {
106             scanf("%d%d", &l, &r);
107             printf("%lld\n", query(l, r, 1));
108         }
109         else 
110         {
111             scanf("%d%d%d", &l, &r, &add);
112             insert(l, r, 1, add);
113         }
114         
115     }
116 
117     return 0;
118 }

 

posted @ 2013-04-24 18:51  旅行的蜗牛  阅读(165)  评论(0编辑  收藏  举报