一個功能較爲全面的線段樹:node
包括區間更新,區間查詢最值(大/小),區間求和c++
有完整註釋以及一道板子題promise
HDU-1166ui
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=5*1e4+7; 4 int seq[maxn]; // must use index from 1 5 6 struct Node{ 7 int l,r,maxx,minn; 8 long long sum,lazy; 9 // lazy for delaying child updating 10 void update(int x){ 11 // update node storage value 12 lazy+=x; 13 sum+=1LL*(l-r+1)*x; // transfrom int to long long 14 maxx+=x; 15 minn+=x; 16 } 17 void __str__(){ 18 printf("l:%d r:%d maxx:%d minn:%d sum:%lld lazy:%lld\n", 19 l,r,maxx,minn,sum,lazy); 20 } 21 }Tree[maxn<<2]; // need 4 times space 22 23 void push_up(int id){ 24 // collect child node information 25 Tree[id].sum=Tree[id<<1].sum+Tree[id<<1|1].sum; 26 Tree[id].maxx=max(Tree[id<<1].maxx,Tree[id<<1|1].maxx); 27 Tree[id].minn=min(Tree[id<<1].minn,Tree[id<<1|1].minn); 28 } 29 30 void push_down(int id){ 31 // only push down lazy to child, not update itselef 32 // change itself value by push_up operation 33 // if node has lazy value , push down lazy to child 34 long long lazyval=Tree[id].lazy; 35 if(lazyval){ 36 // cleaer lazy 37 Tree[id].lazy=0; 38 // update child node, itself not change 39 Tree[id<<1].update(lazyval); 40 Tree[id<<1|1].update(lazyval); 41 } 42 } 43 44 void build(int id,int l,int r){ 45 Tree[id].l=l;Tree[id].r=r;Tree[id].lazy=0; 46 if(l==r){ 47 // leaf node 48 Tree[id].sum=Tree[id].maxx=Tree[id].minn=seq[l]; 49 }else{ 50 // minddle node 51 int mid=l+((r-l)>>1); 52 build(id<<1,l,mid); 53 build(id<<1|1,mid+1,r); 54 // update parent value 55 push_up(id); 56 } 57 } 58 59 void update(int id, int ql,int qr, int val){ 60 int L=Tree[id].l, R=Tree[id].r; 61 if(ql<=L && R<=qr){ 62 // if query range contains range of now node, only to update it, 63 // don't update child, even to update leaf node. 64 // only in this way to promise update operation by O(logn) 65 Tree[id].update(val); 66 }else{ 67 push_down(id); 68 int mid=L+((R-L)>>1); 69 if(ql<=mid) update(id<<1,ql,qr,val); 70 if(mid<qr) update(id<<1|1,ql,qr,val); 71 push_up(id); 72 } 73 } 74 75 long long querySum(int id,int ql,int qr){ 76 int L=Tree[id].l, R=Tree[id].r; 77 if(ql<=L && R<=qr){ 78 // query range contains now node range, it dedicate that we can get result on the node 79 return Tree[id].sum; 80 }else{ 81 push_down(id); 82 long long ans=0; 83 int mid=L+((R-L)>>1); 84 if(ql<=mid) ans+=querySum(id<<1,ql,qr); 85 if(mid<qr) ans+=querySum(id<<1|1,ql,qr); 86 push_up(id); 87 return ans; 88 } 89 } 90 91 int queryMax(int id, int ql, int qr){ 92 int L=Tree[id].l, R=Tree[id].r; 93 if(ql<=L && R<=qr){ 94 return Tree[id].maxx; 95 }else{ 96 push_down(id); 97 int ans=-INF; 98 int mid=L+((R-L)>>1); 99 if(ql<=mid) ans=max(ans,queryMax(id<<1,ql,qr)); 100 if(mid<qr) ans=max(ans,queryMax(id<<1|1,ql,qr)); 101 push_up(id); 102 return ans; 103 } 104 } 105 106 int queryMin(int id, int ql, int qr){ 107 int L=Tree[id].l, R=Tree[id].r; 108 if(ql<=L && R<=qr){ 109 return Tree[id].minn; 110 }else{ 111 push_down(id); 112 int ans=INF; 113 int mid=L+((R-L)>>1); 114 if(ql<=mid) ans=min(ans,queryMin(id<<1,ql,qr)); 115 if(mid<qr) ans=min(ans,queryMin(id<<1|1,ql,qr)); 116 push_up(id); 117 return ans; 118 } 119 } 120 121 int seqGet(int idx){ 122 // get value in seq by index 123 return queryMax(1,idx,idx); 124 } 125 126 int n; 127 int main(int argc, char const *argv[]) 128 { 129 // https://vjudge.net/problem/HDU-1166 130 int T,kase=1; 131 char flag[10]; 132 scanf("%d",&T); 133 while(T--){ 134 scanf("%d",&n); 135 for(int i=1;i<=n;i++) 136 scanf("%d",&seq[i]); 137 build(1,1,n); 138 // print_tree(); 139 printf("Case %d:\n",kase++); 140 int i,j; 141 while(scanf("%s",flag) && flag[0]!='E'){ 142 scanf("%d %d",&i,&j); 143 if(flag[0]=='A') update(1,i,i,j); 144 else if(flag[0]=='S') update(1,i,i,-j); 145 else printf("%lld\n",querySum(1,i,j)); 146 } 147 } 148 return 0; 149 }