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;
}

  

posted @ 2015-03-05 15:54  chenjunjie1994  阅读(166)  评论(0编辑  收藏  举报