第一次写线段树。。。写了一个下午。。。好不容易才弄懂。。。
【神犇mhy12345风格,mhy12345 orz】
注意Query_sgt()中也要下推lazy标记!!!
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<string> 6 using namespace std; 7 #define MAXN 10000 8 #define MAXT MAXN*4 9 int n,a[MAXN+2],topt=0; 10 struct sgt_node{ 11 int lc,rc; 12 int mn; // 维护最小值 13 int lazy; // 懒标记 14 }sgt[MAXT+2]; 15 #define lch sgt[now].lc 16 #define rch sgt[now].rc 17 #define smid ((l+r)>>1) 18 void update(int now){ 19 sgt[now].mn=min(sgt[lch].mn,sgt[rch].mn); 20 } // 值上传 21 void set_lazy(int now,int v){ 22 sgt[now].mn+=v; 23 sgt[now].lazy+=v; 24 } // 更新值并设置标记 25 void push_down(int now){ 26 if(sgt[now].lazy){ 27 set_lazy(lch,sgt[now].lazy); 28 set_lazy(rch,sgt[now].lazy); 29 sgt[now].lazy=0; 30 } 31 } // 标记下传 32 void Build_sgt(int &now,int l,int r){ 33 now=++topt; 34 if(l==r){ 35 sgt[now].mn=a[l]; 36 return; 37 } 38 Build_sgt(lch,l,smid); 39 Build_sgt(rch,smid+1,r); 40 update(now); 41 } 42 int Query_sgt(int now,int l,int r,int qx,int qy){ 43 if(qx==l&&qy==r)return sgt[now].mn; 44 push_down(now); // 在访问节点时需要推下lazy标记 45 if(qy<=smid)return Query_sgt(lch,l,smid,qx,qy); 46 if(qx>smid)return Query_sgt(rch,smid+1,r,qx,qy); 47 return min(Query_sgt(lch,l,smid,qx,smid),Query_sgt(rch,smid+1,r,smid+1,qy)); 48 } 49 void Point_add(int now,int l,int r,int pnt,int v){ 50 if(l==r){ 51 sgt[now].mn+=v; 52 return; 53 } 54 if(pnt<=smid)Point_add(lch,l,smid,pnt,v); 55 else if(pnt>smid)Point_add(rch,smid+1,r,pnt,v); 56 update(now); 57 } 58 void Region_add(int now,int l,int r,int x,int y,int v){ 59 if(x==l&&y==r){ 60 set_lazy(now,v); 61 return; 62 } 63 push_down(now); 64 if(y<=smid)Region_add(lch,l,smid,x,y,v); 65 else if(x>smid)Region_add(rch,smid+1,r,x,y,v); 66 else{ 67 Region_add(lch,l,smid,x,smid,v); 68 Region_add(rch,smid+1,r,smid+1,y,v); 69 } 70 update(now); 71 } 72 int main(){ 73 scanf("%d",&n); 74 for(int i=0;i<n;i++) 75 scanf("%d",a+i); 76 int root=0; 77 Build_sgt(root,0,n-1); 78 // 以下为检测部分 79 string op; 80 cin>>op; 81 while(op!="quit"&&op!="qt"){ 82 if(op=="query"||op=="qr"){ 83 int ql,qr; 84 scanf("%d%d",&ql,&qr); 85 if(ql<0||qr>=n||ql>qr)printf(" Range exceeded!!! "); 86 else printf(" The min value of [%d, %d] is %d ",ql,qr,Query_sgt(1,0,n-1,ql,qr)); 87 } 88 else if(op=="padd"||op=="p"){ 89 int pnt,v; 90 scanf("%d%d",&pnt,&v); 91 if(pnt<0||pnt>=n)printf(" Range exceeded!!! "); 92 else{ 93 Point_add(1,0,n-1,pnt,v); 94 printf(" Add %d to pos %d successfully ",v,pnt); 95 } 96 } 97 else if(op=="radd"||op=="r"){ 98 int x,y,v; 99 scanf("%d%d%d",&x,&y,&v); 100 if(x<0||y>=n||x>y)printf(" Range exceeded!!! "); 101 else{ 102 Region_add(1,0,n-1,x,y,v); 103 printf(" Add %d to each of [%d, %d] successfully ",v,x,y); 104 } 105 } 106 cin>>op; 107 } 108 return 0; 109 }