hdu 1698 Just a Hook(線段樹的區間更新及求和)
阿新 • • 發佈:2019-01-07
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define N 100010 struct Node{ int L; int R; int V; }tree[4*N]; void BuildTree(int root,int l,int r){ tree[root].L=l; tree[root].R=r; tree[root].V=1;///表示顏色,該顏色預設價值為1 if(l==r){ return ; } int mid=(l+r)/2; BuildTree(2*root,l,mid); BuildTree(2*root+1,mid+1,r); } void update(int root,int s,int e,int a){ if(tree[root].V==a){///區間內的顏色與要更新的一樣,不用更新 return ; } if(tree[root].L==s&&tree[root].R==e){///區間相同,直接更新 tree[root].V=a; return ; } if(tree[root].V!=-1){///如果區間的顏色相同,但是與即將跟新的顏色不一樣,則此區間就要變成雜色 tree[2*root].V=tree[2*root+1].V=tree[root].V; ///先將區間的顏色更新到子結點 ///因為每次更新只更新到父節點,如果第二組資料要用到子節點時,就應該先將父節點的顏色給子節點,再標記 tree[root].V=-1;///區間此時不只有一種顏色了,標記為-1 } int mid=(tree[root].L+tree[root].R)/2; if(e<=mid) update(2*root,s,e,a); else if(s>mid) update(2*root+1,s,e,a); else { update(2*root,s,mid,a); update(2*root+1,mid+1,e,a); } } int Query(int root,int s,int e){ if(tree[root].V!=-1){///區間都為同一顏色 return (e-s+1)*tree[root].V; } else{ int mid=(tree[root].L+tree[root].R)/2; if(e<=mid) return Query(2*root,s,e); else if(s>mid) return Query(2*root+1,s,e); else { return Query(2*root,s,mid)+Query(2*root+1,mid+1,e); } } } int main(){ int T,ca=1; scanf("%d",&T); while(T--){ int n; scanf("%d",&n); BuildTree(1,1,n); int m; scanf("%d",&m); while(m--){ int a,b,c; scanf("%d%d%d",&a,&b,&c); update(1,a,b,c); } printf("Case %d: The total value of the hook is %d.\n",ca++,Query(1,1,n)); } return 0; }