线段树模板(DFS序)

HDU - 3974 

#include<bits/stdc++.h>
using namespace std;

#define MAX 100005
vector<int> path[MAX];
int l[MAX],r[MAX];
int book[MAX];

int ct;
void dfs(int u){
	ct++;
	book[u]=1;
	l[u]=ct;
	for(int i=0;i<path[u].size();i++){
		dfs(path[u][i]);
	}
	r[u]=ct;
}

void init(){
	ct=0;
	memset(l,0,sizeof(l));
	memset(r,0,sizeof(r));
	memset(book,0,sizeof(book));
}

char read(){
	char p;
	p=getchar();
	while(p!='C'&&p!='T')
	{
		p=getchar();
	}
	return p;
}

struct node{
	int val;
	int add;
}segtree[MAX<<2];

void build(int root,int nl,int nr){
	segtree[root].val=-1;
	segtree[root].add=-1;
	
	if(nl==nr){
		return ;
	}
	
	int mid=nl+nr>>1;
	build(root<<1,nl,mid);
	build(root<<1|1,mid+1,nr);
}

void pushdown(int root,int nl,int nr){
	if(segtree[root].add!=-1){
		segtree[root<<1].val=segtree[root].add;
		segtree[root<<1|1].val=segtree[root].add;
		
		segtree[root<<1].add=segtree[root].add;
		segtree[root<<1|1].add=segtree[root].add;

		segtree[root].add=-1;
	}
}

void update(int root,int nl,int nr,int ql,int qr,int add){
	if(nl>qr||nr<ql){
		return ;
	}
	
	if(nl>=ql&&nr<=qr){
		segtree[root].val=add;
		segtree[root].add=add;

		return ;
	}

	pushdown(root,nl,nr);
	
	int mid=nl+nr>>1;
	update(root<<1,nl,mid,ql,qr,add);
	update(root<<1|1,mid+1,nr,ql,qr,add);
	
}

void query(int root,int nl,int nr,int ql,int qr,int& ans){
	if(nl>qr||nr<ql){
		return ;
	}

	if(nl>=ql&&nr<=qr){
		ans=segtree[root].val;
		return ;
	}
	
	pushdown(root,nl,nr);
	
	int mid=nl+nr>>1;
	query(root<<1,nl,mid,ql,qr,ans);
	query(root<<1|1,mid+1,nr,ql,qr,ans);

}

int main(){
	int ps;
	cin>>ps;
	
	for(int pp=1;pp<=ps;pp++){
		printf("Case #%d:\n",pp);
		init();
		
		int n;
		scanf("%d",&n);
		
		for(int i=1;i<=n;i++)path[i].clear();

		for(int i=1;i<=n-1;i++){
			int a,b;
			scanf("%d%d",&a,&b);
			book[a]=1;
			path[b].push_back(a);
		}
		
		for(int i=1;i<=n;i++){
			if(!book[i]){
				dfs(i);
				break;
			}
		}
		
		build(1,1,n);
		
		int m;
		scanf("%d",&m);

		for(int i=1;i<=m;i++){
			char c=read();

			if(c=='C'){
				int a;
				scanf("%d",&a);

				int ans=-1;
				query(1,1,n,l[a],l[a],ans);
				printf("%d\n",ans);
			}
			else if(c=='T'){
				int a,b;
				scanf("%d%d",&a,&b);

				update(1,1,n,l[a],r[a],b);
			}
		}
	}
	return 0;
} 

注意query的是该节点,而不是该区间

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值