线段树

struct node{
    int l,r; ll sum,lazy;
}tree[maxn<<2];

void push_up(int rt){
    tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
}

void push_down(int rt){
    if(tree[rt].lazy){
        tree[rt<<1].lazy+=tree[rt].lazy;
        tree[rt<<1|1].lazy+=tree[rt].lazy;
        tree[rt<<1].sum+=tree[rt].lazy*(tree[rt<<1].r-tree[rt<<1].l+1);
        tree[rt<<1|1].sum+=tree[rt].lazy*(tree[rt<<1|1].r-tree[rt<<1|1].l+1);
        tree[rt].lazy=0;
    }
}

void build_tree(int l,int r,int rt){
    tree[rt].lazy=0;
    tree[rt].l=l;
    tree[rt].r=r;
    if(l==r){
        tree[rt].sum=0;
        return;
    }
    int mid=l+r>>1;
    build_tree(l,mid,rt<<1);
    build_tree(mid+1,r,rt<<1|1);
    push_up(rt);
}

void update_interval(int l,int r,int rt,int v){
    if(l<=tree[rt].l&&r>=tree[rt].r){
        tree[rt].lazy+=v;
        tree[rt].sum+=v*(tree[rt].r-tree[rt].l+1);
        return;
    }
    if(tree[rt].lazy)
        push_down(rt);
    int mid=tree[rt].l+tree[rt].r>>1;
    if(l<=mid)
        update_interval(l,r,rt<<1,v);
    if(r>mid)
        update_interval(l,r,rt<<1|1,v);
    push_up(rt);
}

ll query_interval(int l,int r,int rt){
    if(l<=tree[rt].l&&r>=tree[rt].r)
        return tree[rt].sum;
    if(tree[rt].lazy)
        push_down(rt);
    int mid=tree[rt].l+tree[rt].r>>1;
    ll ans=0;
    if(l<=mid)
        ans+=query_interval(l,r,rt<<1);
    if(r>mid)
        ans+=query_interval(l,r,rt<<1|1);
    return ans;
}

void update_single(int p,int v,int rt){
    if(tree[rt].l==tree[rt].r&&tree[rt].r==p){
        tree[rt].sum=v;
        return;
    }
    int mid=tree[rt].l+tree[rt].r>>1;
    if(p<=mid)
        update_single(p,v,rt<<1);
    else
        update_single(p,v,rt<<1|1);
    push_up(rt);
}

int query_single(int p,int rt){
    if(tree[rt].l==tree[rt].r&&tree[rt].r==p){
        return tree[rt].sum;
    }
    if(tree[rt].lazy)
        push_down(rt);
    int mid=tree[rt].l+tree[rt].r>>1;
    if(p<=mid)
        query_single(p,rt<<1);
    else
        query_single(p,rt<<1|1);
}

你可能感兴趣的:(线段树)