线段树区间修改及查询区间和

只愿长相守 提交于 2019-11-27 22:04:12
void update(int p)
{
    if(t[p].add)
    {
        t[p*2].sum+=(t[p*2].r-t[p*2].l+1)*t[p].add;
        t[p*2+1].sum+=(t[p*2+1].r-t[p*2+1].l+1)*t[p].add;
        t[p*2].add+=t[p].add;
        t[p*2+1].add+=t[p].add;
        t[p].add=0;
    }
}
void change(int p,int l,int r,int d)
{
    if(l<=t[p].l&&r>=t[p].r)
    {
        t[p].sum+=(t[p].r-t[p].l+1)*d;
        t[p].add+=d;
        return;
    }
    update(p);
    int mid=(t[p].l+t[p].r)/2;
    if(l<=mid) change(p*2,l,r,d);
    if(r>mid) change(p*2+1,l,r,d);
    t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
void build(int p,int l,int r)
{
    t[p].l=l,t[p].r=r;t[p].sum=0,t[p].add=0;
    if(l==r)
    {
        t[p].sum=t[p].add=0;
        return;
    }
    int mid=(l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
ll ask(int p,int l,int r)
{
    if(l<=t[p].l&&r>=t[p].r) return t[p].sum;
    update(p);
    int mid=(t[p].l+t[p].r)/2;
    ll val=0;
    if(l<=mid) val+=ask(p*2,l,r);
    if(r>mid) val+=ask(p*2+1,l,r);
    return val;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!