1. 程式人生 > >HDOJ 1698 Just a Hook (線段樹區間更新求區間和)

HDOJ 1698 Just a Hook (線段樹區間更新求區間和)

setv[o]表示o結點以下的所有兒子節點上f都沒有被更新。

#include<cstdio>
using namespace std;
#define ls o<<1
#define rs o<<1|1
# define root 1,1,n
const int MAXN = 500010;
int f[4*MAXN],setv[4*MAXN];
void maintain(int o,int l,int r)
{
    if(setv[o]) f[o] = (r-l+1)*setv[o];
    else f[o] = f[ls]+f[rs];
}
void pushdown(int o,int l,int r)
{
    setv[ls] = setv[rs] = setv[o];
    setv[o] = 0;
    int m = (l+r)>>1;
    maintain(ls,l,m);
    maintain(rs,m+1,r);
}
void build(int o,int l,int r)//建樹
{
    setv[o] = 0;
    if(l == r) {f[o] = 1; return;}
    int m = (l+r)>>1;
    build(ls,l,m);
    build(rs,m+1,r);
    f[o] = f[ls] + f[rs];
}
void update(int ql,int qr,int v,int o,int l,int r)//更新
{
    if(ql <= l && qr >= r) setv[o] = v;
    else
    {
        if(setv[o]) pushdown(o,l,r);
        int m = (l+r)>>1;
        if(ql <= m) update(ql,qr,v,ls,l,m);
        if(qr > m) update(ql,qr,v,rs,m+1,r);
    }
    maintain(o,l,r);
}
int query(int ql,int qr,int o,int l,int r)//查詢
{
    if(ql <= l && qr >= r) return f[o];
    if(setv[o]) pushdown(o,l,r);
    int m = (l+r)>>1,sum = 0;
    if(ql <= m) sum  += query(ql,qr,ls,l,m);
    if(qr > m) sum += query(ql,qr,rs,m+1,r);
    return sum;
}
int main()

    int T,n,m,cas = 0;
    int a,b,c;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        build(root);
        while(m--)
        {
            scanf("%d%d%d",&a,&b,&c);
            update(a,b,c,root);
        }
        printf("Case %d: The total value of the hook is %d.\n",++cas,query(1,n,root)); 
    }
}