友情OI链接  mhy12345 |  Acheing |  翠竹叶飞 |  罗嘉诚(pas) |  欧阳创宇

【原创】线段树(求区间最小值)

 

第一次写线段树。。。写了一个下午。。。好不容易才弄懂。。。

【神犇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("\tRange exceeded!!!\n");
 86             else printf("\tThe min value of [%d, %d] is %d\n",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("\tRange exceeded!!!\n");
 92             else{
 93                 Point_add(1,0,n-1,pnt,v);
 94                 printf("\tAdd %d to pos %d successfully\n",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("\tRange exceeded!!!\n");
101             else{
102                 Region_add(1,0,n-1,x,y,v);
103                 printf("\tAdd %d to each of [%d, %d] successfully\n",v,x,y);
104             }
105         }
106         cin>>op;
107     }
108     return 0;
109 }

 

posted @ 2017-07-20 17:09  Darkleafin  阅读(782)  评论(0编辑  收藏  举报