线段树---->成段更新

虽然对代码有调试,理解,但是可能注释也不一定对。。

总之就是线段树学的太水了。。递归思想也不太清楚啊。哭死

PS:大牛勿喷,弱菜贴代码只是为了以后查看 T T

  1 //该题与hdu1166的敌兵布阵不同在于,该题是成段更新,而敌兵布阵是单点更新
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 #define lmax x<<1
  7 #define rmax x<<1|1
  8 #define MAX 211111
  9 #define LL long long
 10 using namespace std;
 11 
 12 LL sum[MAX<<2];
 13 LL add[MAX<<2]; //标记数组,用于标记,这样就不用每次都全部更新子节点。记录更新一段的权值
 14 
 15 void PushUp(int node) //更新父节点
 16 {
 17     sum[node] = sum[node<<1] + sum[node<<1|1];
 18     return ;
 19 }
 20 
 21 void Build_Tree(int x, int l, int r)
 22 {
 23     add[x] = 0;
 24     if( l == r )
 25     {
 26         cin>>sum[x];
 27         return ;
 28     }
 29     int mid = (l + r) >> 1;
 30     Build_Tree(lmax, l, mid);
 31     Build_Tree(rmax, mid+1, r);
 32     PushUp(x);
 33 }
 34 
 35 void PushDown(int node, int m)  //更新子节点
 36 {
 37     if( add[node] ) //如果该节点有权值,就直接更新它的左右子节点,不用一直更新下去
 38     {
 39         add[node<<1|1] += add[node]; //更新权值
 40         add[node<<1] += add[node];
 41         sum[node<<1] += (m - (m >> 1)) * add[node]; //(m-(m>>1))是表示该节点有几个左子节点
 42         sum[node<<1|1] += (m>>1) * add[node]; //m>>1表示有多少个右子节点
 43         add[node] = 0;
 44     }
 45 }
 46 
 47 void Update(int L, int R, int date, int x, int l, int r) //更新节点
 48 {
 49     if( L <= l && r <= R )
 50     {
 51         add[x] += date;
 52         sum[x] += (LL)date * (r - l + 1); //(r-l+1)表示的是有多少个子节点
 53         return ;
 54     }
 55     PushDown(x, r-l+1);
 56     int mid = (l + r) >> 1;
 57     if( L <= mid )
 58     {
 59         Update(L, R, date, lmax, l, mid);
 60     }
 61     if( R > mid )
 62     {
 63         Update(L, R, date, rmax, mid + 1, r);
 64     }
 65     PushUp(x);
 66 }
 67 
 68 LL Query(int L, int R, int x, int l, int r)
 69 {
 70     if( L <= l && r <= R )
 71     {
 72         return sum[x];
 73     }
 74     PushDown(x, r-l+1);
 75     int mid = (l + r) >> 1;
 76     LL res = 0;            //用于区间求和
 77     if( L <= mid )
 78     {
 79         res += Query(L, R, lmax, l, mid);
 80     }
 81     if( R > mid )
 82     {
 83         res += Query(L, R, rmax, mid+1, r);
 84     }
 85     return res;
 86 }
 87 
 88 int main()
 89 {
 90     int n, Q;
 91     while( cin>>n>>Q )
 92     {
 93         Build_Tree(1, 1, n);
 94         while( Q-- )
 95         {
 96             char operation[2];
 97             int a, b, c;
 98             cin>>operation;
 99             if( operation[0] == 'Q' )
100             {
101                 cin>>a>>b;
102                 LL answer = Query(a, b, 1, 1, n);
103                 cout<<answer<<endl;
104             }
105             else
106             {
107                 cin>>a>>b>>c;
108                 Update(a, b, c, 1, 1, n);
109             }
110         }
111     }
112     return 0;
113 }