线段树---->成段更新
虽然对代码有调试,理解,但是可能注释也不一定对。。
总之就是线段树学的太水了。。递归思想也不太清楚啊。哭死
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 }
浙公网安备 33010602011771号