[模板]基本线段树操作

嗑两天的线段树,终于tm学会了

结构体构造

struct Node
{
    int l,r;
    int w,tag;
}Tree[4*N+1];

建树

void build(int p,int l,int r)
{
    Tree[p].l=l;
    Tree[p].r=r;
    if(l==r){
        Tree[p].w=A[l];
        return;
    }
    int mid=(l+r)>>1;
    build(lson(p),l,mid);
    build(rson(p),mid+1,r);
    Tree[p].w=Tree[lson(p)].w+Tree[rson(p)].w;
    return;
}

下传延迟标记

void add(int p,int l,int r,int k)
{
    Tree[p].w+=(r-l+1)*k;
    Tree[p].tag+=k;
    return;
}
void down(int p,int l,int r)
{
    if(!Tree[p].tag)return;
    int mid=(l+r)>>1;
    add(lson(p),l,mid,Tree[p].tag);
    add(rson(p),mid+1,r,Tree[p].tag);
    Tree[p].tag=0;
    return;
}

区间加法

void modify(int p,int x,int y,int l,int r,ll k)
{
    if(y<l||x>r)return;
    if(x<=l&&r<=y){
        Tree[p].w+=k*(r-l+1);
        Tree[p].tag+=k;
        return;
    }
    down(p,l,r);
    int mid=(l+r)>>1;
    if(x<=mid)modify(lson(p),x,y,l,mid,k);
    if(y>mid)modify(rson(p),x,y,mid+1,r,k);
    Tree[p].w=Tree[lson(p)].w+Tree[rson(p)].w;
    return;
}

区间询问和

int query(int p,int l,int r,int x,int y)
{
    if(y<l||x>r)return 0;
    if(x<=l&&r<=y)return Tree[p].w;
    down(p,l,r);
    int mid=(l+r)>>1;
    int res=0;
    if(x<=mid)res+=query(lson(p),l,mid,x,y);
    if(y>mid)res+=query(rson(p),mid+1,r,x,y);
    return res;
}

猜你喜欢

转载自www.cnblogs.com/lihepei/p/10113509.html
今日推荐