线段树(大三的模板)

Up函数  用来更新父亲节点的值
void push(int w)
{
    sum[w] = sum[2*w]+sum[2*w+1];//更新节点值
}

单点更新 先找出第p个数 然后更新他的值

void add(int p,int d,int l,int r,int w)
{
    if(l==r)
    {
       sum[w]+=d;
          return ;
    }
    int m = (l+r)/2;
    if(p<=m)
        add(p,d,l,m,2*w);
    else
        add(p,d,m+1,r,2*w+1);
    push(w);
}

******************************************

区间求和

int query(int p1,int p2,int l,int r,int w)
{
    if(p1<=l&&p2>=r)//区间被完全覆盖
        return sum[w];    
    int m = (l+r)/2;
    int re = 0;
    if(p1<=m)
        re+=query(p1,p2,l,m,2*w);
    if(p2>m)
        re+=query(p1,p2,m+1,r,2*w+1);
    return re;
}

***************************************88

区间更新
down 函数

void pushdown(int w,int m)
{
    if(lz[w])
    {
        lz[2*w]+=lz[w];
        lz[2*w+1] += lz[w];
        sum[2*w] += (lz[w]*(m-(m/2)));
        sum[2*w+1]+=(lz[w]*(m/2));
        lz[w] = 0;//将延迟标记去除
    }
}


void update(int a,int b,int da,int l,int r,int w)
    {
        if(a<=l&&b>=r)
        {
            lz[w] += da;//多次延迟标记
            sum[w]+=da*(r-l+1);
            return ;
        }
        pushdown(w,r-l+1);//更新
        int m = (l+r)/2;
        if(a<=m)
            add(a,b,da,l,m,2*w);
        if(b>m)
            add(a,b,da,m+1,r,2*w+1);
        pushup(w);
    }

 

posted @ 2014-08-08 21:22  我喜欢旅行  阅读(177)  评论(0编辑  收藏  举报