Duan2baka的线段树模板!

来源:互联网 发布:托马斯·哈里斯 知乎 编辑:程序博客网 时间:2024/06/13 10:40

区间加(Add_Seq),区间修改(Modify_Seq),区间求和(Query),区间最大值(Query_MAX),单点加(Add),单点修改(Modify)
有待补充…

#include<algorithm>#include<ctype.h>#include<cstdio>#define N 100050using namespace std;inline int read(){    int x=0,f=1;char c=getchar();    while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}    while(isdigit(c)) x=(x<<3)+(x<<1)+c-'0',c=getchar();    return x*f;}int a[N];struct Seg{    int l,r,sum,lazy,maxx,add;    Seg *ls,*rs;}root;inline void Update(Seg *k){    if(k->ls==NULL) return;    k->sum=k->ls->sum+k->rs->sum;    k->maxx=max(k->ls->maxx,k->rs->maxx);}inline void Pushdown_MOD(Seg *k){    if(k->lazy==-1) return;    if(k->ls!=NULL){        k->ls->lazy=k->lazy;        k->ls->maxx=k->lazy;        k->ls->sum=(k->ls->r-k->ls->l+1)*k->lazy;    }    if(k->rs!=NULL){        k->rs->lazy=k->lazy;        k->rs->maxx=k->lazy;        k->rs->sum=(k->rs->r-k->rs->l+1)*k->lazy;    }    k->lazy=-1;}inline void Pushdown_Add(Seg *k){    if(k->add==0) return;    if(k->ls!=NULL){        k->ls->add+=k->add;        k->ls->maxx+=k->add;        k->ls->sum+=(k->ls->r-k->ls->l+1)*k->add;    }    if(k->rs!=NULL){        k->rs->add+=k->add;        k->rs->maxx+=k->add;        k->rs->sum+=(k->rs->r-k->rs->l+1)*k->add;    }    k->add=0;}inline void Pushdown(Seg *k){    Pushdown_MOD(k);    Pushdown_Add(k);}void maketree(int l,int r,Seg *k){    k->l=l;k->r=r;k->add=0;    if(l==r){        k->sum=0;k->maxx=0;        return;    }    int mid=l+r>>1;    k->ls=new(Seg);k->rs=new(Seg);    maketree(l,mid,k->ls);maketree(mid+1,r,k->rs);    Update(k);}void remake(Seg *k){    k->lazy=-1;k->add=0;    if(k->l==k->r){        k->sum=k->maxx=a[k->l];        return;    }    remake(k->ls);remake(k->rs);    Update(k);}void Delete(Seg *k){    if(k->ls!=NULL){        Delete(k->ls);    }    if(k->rs!=NULL){        Delete(k->rs);    }    delete(k);}void Add(int x,int v,Seg *k){    if(k->l==k->r){        k->sum+=v;        return;    }    int mid=(k->l+k->r)>>1;    if(x<=mid) Add(x,v,k->ls);    else Add(x,v,k->rs);    Update(k);}int Query(int x,int y,Seg *k){    if(x<=k->l && y>=k->r){        return k->sum;    }    int mid=(k->l+k->r)>>1,t;    Pushdown(k);Update(k);    if(y<=mid) t=Query(x,y,k->ls);    else if(x>mid) t=Query(x,y,k->rs);    else t=Query(x,y,k->ls)+Query(x,y,k->rs);    Pushdown(k);Update(k);    return t;}int Query_MAX(int x,int y,Seg *k){    if(x<=k->l && y>=k->r){        return k->maxx;    }    Pushdown(k);    int mid=(k->l+k->r)>>1;    if(y<=mid) return Query_MAX(x,y,k->ls);    if(x>mid) return Query_MAX(x,y,k->rs);    return max(Query_MAX(x,y,k->ls),Query_MAX(x,y,k->rs));}void Modify(int x,int v,Seg *k){    if(k->l==k->r){        k->sum=v;        k->maxx=v;        return;    }    int mid=(k->l+k->r)>>1;    if(x<=mid) Modify(x,v,k->ls);    else Modify(x,v,k->rs);    Update(k);}void Modify_Seq(int x,int y,int v,Seg *k){    if(k->l>=x && k->r<=y){        k->lazy=v;        k->maxx=v;k->sum=(k->r-k->l+1)*v;        return;    }    Pushdown(k);    int mid=(k->l+k->r)>>1;    if(y<=mid) Modify_Seq(x,y,v,k->ls);    else if(x>mid) Modify_Seq(x,y,v,k->rs);    else Modify_Seq(x,y,v,k->ls),Modify_Seq(x,y,v,k->rs);    Update(k);}void Add_Seq(int x,int y,int v,Seg *k){    if(k->l>=x && k->r<=y){        k->add=k->add+v;        k->maxx=k->maxx+v;        k->sum=k->sum+(k->r-k->l+1)*v;        return;    }    Pushdown(k);Update(k);    int mid=(k->l+k->r)>>1;    if(y<=mid) Add_Seq(x,y,v,k->ls);    else if(x>mid) Add_Seq(x,y,v,k->rs);    else Add_Seq(x,y,v,k->ls),Add_Seq(x,y,v,k->rs);    Pushdown(k);Update(k);}main(){return 0;}