HDU 1698
成段更新,使用标记向下传递的方法,当前Now被染色,向下传可分成两半,这样,在处理另一半时,其中一半仍保存着正确的颜色。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string.h> #include <queue> #include <cmath> #include <map> #include <vector> #define LL __int64 using namespace std; const int N=100050; const int root=1; struct Node { int col; int val,left,right; }tree[N*4]; void build(int now,int l,int r){ tree[now].col=0; tree[now].left=l; tree[now].right=r; if(l==r){ tree[now].val=1; return; } int m=(l+r)>>1; build(now*2,l,m); build(now*2+1,m+1,r); tree[now].val=tree[now*2].val+tree[now*2+1].val; } void Deliver_Down(int now){ if(tree[now].col>0){ tree[now*2].col=tree[now*2+1].col=tree[now].col; tree[now*2].val=(tree[now*2].right-tree[now*2].left+1)*tree[now*2].col; tree[now*2+1].val=(tree[now*2+1].right-tree[now*2+1].left+1)*tree[now*2+1].col; tree[now].col=0; } } void update(int now,int l,int r,int u){ int L=tree[now].left,R=tree[now].right; if(l<=L&&r>=R){ tree[now].val=(R-L+1)*u; tree[now].col=u; return ; } Deliver_Down(now); int m=(L+R)/2; if(r<=m){ update(now*2,l,r,u); } else if(l>=m+1) update(now*2+1,l,r,u); else{ update(now*2,l,r,u); update(now*2+1,l,r,u); } tree[now].val=tree[now*2].val+tree[now*2+1].val; } int main(){ int T,act,n,x,y,u,t=0; scanf("%d",&T); while(T--){ scanf("%d",&n); build(root,1,n); scanf("%d",&act); for(int i=1;i<=act;i++){ scanf("%d%d%d",&x,&y,&u); update(root,x,y,u); } printf("Case %d: The total value of the hook is %d.\n",++t,tree[root].val); } return 0; }