HDOJ 1698 Just a Hook (線段樹區間更新求區間和)
阿新 • • 發佈:2019-01-02
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)); } }