模板_线段树

来源:互联网 发布:php base64编码 编辑:程序博客网 时间:2024/05/16 18:44

最小值查询

int ql,qr;//查询[ql,qr]最小值int query(int o,int l,int r){    int m=l+(l+r)/2,ans=INF;    if(ql<=l&&qr>=r) return minv[o];//包含    if(ql<=m) ans=min(ans,query(o*2,l,m));//left    if(m<qr) ans=min(ans,query(o*2+1,m+1,r));//right    return ans;}

点修改

int p,v;void updata(int o,int l,int r){    int m=l+(l+r)/2;    if(l==r) minv[o]=v;//叶节点    else{        if(p<=m) updata(o*2,l,m);//左子树        else updata(o*2+1,m+1,r);//右子树        minv[o]=min(minv[o*2],minv[o*2+1]);    }}

信息维护

void maintain(int o,int l,int r){    int lc=o*2,rc=o*2+1;    sumv[o]=minv[o]=maxv[o]=0;    if(r>l){        sumv[o]=sumv[lc,rc];        minv[o]=min(minv[lc],minv[rc]);        maxv[o]=max(maxv[lc],maxv[rc]);    }    minv[o]+=addv[o];maxv[o]+=addv[o];sumv[o]+=addv*(r-l+1);}

add操作

void updata(int o,int l,int r){    int lc=o*2,rc=o*2+1;    if(y1<=l&&y2>=r){        addv[o]+=v;    }    else{        int m=l+(l+r)/2;        if(y1<=m) updata(lc,l,m);        if(y2>m) updata(rc,m+1,r);     }    maintain(o,l,r);//维护区间信息}

区间查询

int _min,_max,_sum;void query(int o,int l,int r,int add){    if(y1<=l&&r2>=r){        _sum+=sumv[o]+add*(r-l+1);        _min=min(_min,minv[o]+add);        _max=max(_max,maxv[o]+add);    }    else{        int m=l+(l+r)/2;        if(y1<=m) query(o*2,l,m,add+addv[o]);        if(y2>m) query(o*2+1,m+1,r,add+addv[o]);    }}

区间全部修改

void updata(int o,int l,int r){    int lc=o*2,rc=lc+1;    if(y1<=l&&y2>=r){        setv[o]=v;    }else{        pushdown(o);        int m=l+(l+r)/2;        if(y1<=m) updata(lc,l,m);        if(y2>m) updata(rc,m+1,r);    }    maintain(o,l,r);}

标记传递

void pushdown(o){    int lc=o*2,rc=lc+1;    if(setv[o]>=0){        setv[lc]=setv[rc]=setv[o];        setv[o]=-1;//清除标记    }}

set的区间查询

int _min,_max,_sum;void query(int o,int l,int r){    if(setv[o]>=0){        _sum+=setv[o]*(min(r,y2)-max(l,y1)+1);        _min=min(_min,setv[o]);        _max=max(_max,setv[o]);    }    else if(y1<=l&&r2>=r){        _sum+=sumv[o];        _min=min(_min,minv[o]);        _max=max(_max,maxv[o]);    }    else{        int m=l+(l+r)/2;        if(y1<=m) query(o*2,l,m);        if(y2>m) query(o*2+1,m+1,r);    }}
1 0