hdu1698线段树区间更新

题目链接:https://vjudge.net/contest/66989#problem/E

坑爹的线段树照着上一个线段树更新写的,结果发现有一个地方就是不对,找了半天,发现是延迟更新标记加错了!!!以后一定要小心这一点

不用query,用value【1】也能ac,但是时间要的多,不知道是为什么,明明调用函数比较慢

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
const int maxn=100100;
ll value[maxn<<2],add[maxn<<2];
void pushup(int rt)//向上更新
{
    value[rt]=value[rt<<1]+value[rt<<1|1];
}
void pushdown(int rt,int m)//向下更新
{
    if(add[rt])
    {
        add[rt<<1]=add[rt];//延迟标记向下更新
        add[rt<<1|1]=add[rt];
        value[rt<<1]=(m-(m>>1))*add[rt];//价值向下更新
        value[rt<<1|1]=(m>>1)*add[rt];
        add[rt]=0;//延迟标记清0
    }
}
void btree(int l,int r,int rt)
{
    add[rt]=0;
    if(l==r)
    {
        value[rt]=1;
        return ;
    }
    int m=(l+r)>>1;
    btree(ls);
    btree(rs);
    pushup(rt);
}
void update(int L,int R,int c,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        add[rt]=c;
        value[rt]=(ll)c*(r-l+1);
        return ;
    }
    pushdown(rt,r-l+1);
    int m=(l+r)>>1;
    if(L<=m)update(L,R,c,ls);
    if(R>m)update(L,R,c,rs);
    pushup(rt);
}
/*ll query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)return value[rt];
    pushdown(rt,r-l+1);
    int m=(l+r)>>1;
    ll ans=0;
    if(L<=m)ans+=query(L,R,ls);
    if(R>m)ans+=query(L,R,rs);
    return ans;
}*/
int main()
{
    int t,n,m;
    scanf("%d",&t);
    for(int i=1;i<=t;i++)
    {
        scanf("%d%d",&n,&m);
        btree(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.
",i,value[1]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/acjiumeng/p/6496352.html