线段树(大三的模板)

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);

    }

 

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