线段树(简单模板)

来源:互联网 发布:咨询公司面试数据分析 编辑:程序博客网 时间:2024/06/03 11:18
#define LL long longstruct hh{    int l,r,ls,rs;//l,r为边界,ls,rs为左右儿子的编号     LL date;//权值 }t[800000];LL n,m,num=0,x,y,v,pd,a[200010],add[200010];//add为标记要增大的值的数组 void pushup(int i)//重新求权值 {    t[i].date=t[t[i].ls].date+t[t[i].rs].date;}void build(int l,int r)//建树 {    num++;    add[num]=0;    t[num].date =0;    int node=num;    t[node].l=l;    t[node].r=r;     if(l!=r)     {        t[node].ls=num+1;        build(l,(l+r)/2);        t[node].rs=num+1;        build(((l+r)/2)+1,r);        pushup(node);     }     else if(l==r)     {        t[node].date=a[l];     }}void pushdown(int i)//把标记传下去 {    if(add[i]!=0) //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!    {        int ls=t[i].ls;int rs=t[i].rs;    add[ls]+=add[i];add[rs]+=add[i];    t[ls].date+=add[i]*(t[ls].r-t[ls].l+1);    t[rs].date+=add[i]*(t[rs].r-t[rs].l+1);    add[i]=0;    }}void update(int i,int l,int r,int v)//更新函数 {    if(t[i].l==l&&t[i].r==r)    {        add[i]+=v;        t[i].date+=add[i]*(r-l+1);        return ;    }    if(t[i].l==t[i].r) return ;    pushdown(i);    int z=t[i].l+t[i].r;    z/=2;    if(r<=z) update (t[i].ls,l,r,v);    else if(l>z) update(t[i].rs,l,r,v);    else     {        update(t[i].ls,l,z,v);        update(t[i].rs,z+1,r,v);    }    pushup(i);}LL query(int i,int l,int r)//求和函数 {    if(t[i].l==l&&t[i].r==r)    return t[i].date ;    pushdown(i);    int z=(t[i].l+t[i].r)/2;    if(r<=z) return query(t[i].ls,l,r);    else if(l>z) return query(t[i].rs,l,r);    else    {        return query(t[i].ls,l,z)+query(t[i].rs,z+1,r);    } }
原创粉丝点击