线段树(简单模板)

#define LL long long
struct 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);
    } 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值