线段树

 

 

线段树模板

线段树就是二叉树加上一个迟缓标记,在进行区间修改的时候不直接修改整个区间的值,而是先对子树的根节点打上标记,标记可以累加,等到查询的时候再下放标记。

 此处为区间修改的模板。

#include<bits/stdc++.h>
using namespace std;
const int MAXN=200005;
struct treeN{
    int val;
    int addM;//迟缓标记
}tree[MAXN*4];
int arr[MAXN];
void pushup(int o){
     tree[o].val=tree[o<<1].val+tree[o<<1|1].val;
 }
 
void build(int o,int l,int r){
    if(l==r)tree[o].val=arr[l];
    else{
        int m=l+((r-l)>>1);    
        build(o<<1,l,m);
        build((o<<1)|1,m+1,r);
        tree[o].val=tree[o<<1].val+tree[(o<<1)|1].val;
    }
}
void pushdown(int o,int l,int r){
     if(tree[o].addM){
         int c=tree[o].addM;
         tree[o<<1].addM=c;
         tree[o<<1|1].addM=c;
         int m=l+((r-l)>>1);
         tree[o<<1].val=(m-l+1)*c;
         tree[o<<1|1].val=(r-m)*c;
         tree[o].addM=0;
     }
 }
 
 void update(int o,int l,int r,int ql,int qr,int c){
     if(ql<=l&&qr>=r){    
         tree[o].addM=c;
         tree[o].val=(r-l+1)*c;
         return;
     }
     
     pushdown(o,l,r);
     int m=l+((r-l)>>1);
     if(ql<=m)update(o<<1,l,m,ql,qr,c);
     if(qr>=m+1)update(o<<1|1,m+1,r,ql,qr,c);
     pushup(o);
 }
 
 int query(int o,int l,int r,int ql,int qr){
     if(ql<=l&&qr>=r) return tree[o].val;
     pushdown(o,l,r);
     int m=l+((r-l)>>1);
     int ans=0;
     if(ql<=m)ans+=query(o<<1,l,m,ql,qr);
     if(qr>=m+1)ans+=query(o<<1|1,m+1,r,ql,qr);
     return ans;
 }
int main(){
    int n,i,j,x,y,m;
    cin>>n;
    for(i=1;i<=n;i++)
        arr[i]=1;
    build(1,1,n);
    cin>>m;
   // cout<<query(0,0,n-1,0,n-1)<<endl;
    for(i=0;i<m;i++){
        
            scanf("%d%d%d",&x,&y,&j);
            update(1,1,n,x,y,j);
        int sum=query(1,1,n,1,n);
    cout<<sum<<endl;
        
    }
    
}

 

 

 

posted @ 2019-04-09 21:09  wengsy150943  阅读(120)  评论(0)    收藏  举报