hdu 1698 线段树 区间更新

感觉线段树要好好练一练。。。跟着大牛的pdf吧。。
http://acm.hdu.edu.cn/showproblem.php?pid=1698
区间更新主要运用的是一个lazy操作,就是说每次更新的时候不要更新到底,运用lazy标志将更新延迟到下次更新或者是查询的时候。
题意:
每次可以修改一段区间的值,最后查询整个的和。(所以查询函数都可以不写了。直接查根节点。。)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 111111
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int laz[M<<2];
int sum[M<<2];
int n;
void pushup(int rt)
{
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void pushdown(int rt,int len)
{
    if(laz[rt])
    {
        laz[rt<<1] = laz[rt<<1|1] = laz[rt]; //将laz标志推下去
        sum[rt<<1] = (len - (len>>1)) * laz[rt]; //更新子节点的值
        sum[rt<<1|1] = (len>>1) * laz[rt];
        laz[rt] = 0; //清除标志
    }
}
void update(int a,int b,int c,int l,int r,int rt)
{
    if(a <= l && r <= b)
    {
        laz[rt] = c;
        sum[rt] = (r-l+1)*c;
        return ;
    }
    pushdown(rt,r-l+1);
    int m = (l+r)>>1;
    if(a <= m) update(a,b,c,lson); //递归更新左儿子
    if(b > m) update(a,b,c,rson); //右儿子
    pushup(rt);
}
void build(int l,int r,int rt)
{
    laz[rt] = 0; //初始化所有节点的laz标志
    if(l == r)
    {
        sum[rt] = 1; //将叶子节点初始化为1
        return ;
    }
    int m = (l+r)>>1;
    build(lson);
    build(rson);
    pushup(rt);
}
int main()
{
    int t;
    scanf("%d",&t);
    for(int cas = 1;cas <= t;cas++)
    {
        scanf("%d",&n);
        build(1,n,1);
        int Q;
        scanf("%d",&Q);
        while(Q--)
        {
            int a,b,c;
            scanf("%d %d %d",&a,&b,&c);
            update(a,b,c,1,n,1);
        }
        printf("Case %d: The total value of the hook is %d.\n",cas,sum[1]);
    }
    return 0;
}

你可能感兴趣的:(hdu 1698 线段树 区间更新)