线段树hdu1698区间更新模板题

区间更新需要用到延迟标记

即每次更新时,不需要更新到底,当搜索的区间在更新或者询问的区间内,就更新该区间并且加上延迟标记然后返回;
当下次更新或者询问时,先pushdown(按照延迟标记更新子树),然后再搜索左右子树(按照当前状态更新或者询问)
#include <cstdio>

using namespace std;

const int maxn = 100010;

int mark[maxn<<2];
int sumtr[maxn<<2];

void build(int l, int r, int rt);
void update(int L, int R, int x, int l, int r, int rt);
void pushup(int rt);
void pushdown(int rt, int len);

int main()
{
    int t, n, m;
    int cas;
    scanf("%d", &t);
    for(cas = 1; cas <= t; ++cas)
    {
        scanf("%d %d", &n, &m);
        build(1, n, 1);
        while(m--)
        {
            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, sumtr[1]);
    }
    return 0;
}

void pushdown(int rt, int len)
{
    if(!mark[rt]) return;
    mark[rt<<1] = mark[rt<<1|1] = mark[rt];
    sumtr[rt<<1] = (len - (len>>1)) * mark[rt];
    sumtr[rt<<1|1] = (len>>1) * mark[rt];
    mark[rt] = 0;
}

void update(int L, int R, int x, int l, int r, int rt)
{
    if(L <= l && r <= R)
    {
        mark[rt] = x;
        sumtr[rt] = x * (r - l + 1);
        return;
    }
    pushdown(rt, r - l + 1);
    int mid = (l + r)>>1;
    if(L <= mid) 
        update(L, R, x, l, mid, rt<<1);
    if(R >= mid + 1) 
        update(L, R, x, mid + 1, r, rt<<1|1);
    pushup(rt);
}

void pushup(int rt)
{
    sumtr[rt] = sumtr[rt<<1] + sumtr[rt<<1|1];
}

void build(int l, int r, int rt)
{
    mark[rt] = 0;
    sumtr[rt] = 1;
    if(l == r) return ;
    int mid = (l + r)>>1;
    build(l, mid, rt<<1);
    build(mid + 1, r, rt<<1|1);
    pushup(rt);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值