BZOJ4551 [Tjoi2016&Heoi2016]树

TJOI居然考这么傻逼的题……根JLOI一比真是天壤之别-_-

转成dfs序,然后相当于区间以deep为关键字去max,直接线段树维护就好

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
using namespace std;
#define MAXN 100010
#define MAXM 1010
#define ll long long
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
struct vec{
	int to;
	int fro;
};
vec mp[MAXN];
int tai[MAXN],cnt;
int ch[MAXN*4];
int dep[MAXN]; 
int dfn[MAXN],siz[MAXN],tim;
int n,m;
inline void be(int x,int y){
	mp[++cnt].to=y;
	mp[cnt].fro=tai[x];
	tai[x]=cnt;
}
void dfs(int x){
	int i,y;
	siz[x]=1;
	dfn[x]=++tim;
	for(i=tai[x];i;i=mp[i].fro){
		y=mp[i].to;
		if(!siz[y]){
			dep[y]=dep[x]+1;
			dfs(y);
			siz[x]+=siz[y];
		}
	}
}
inline void toch(int x,int y){
	if(dep[y]>dep[ch[x]]){
		ch[x]=y;
	}
}
inline void pd(int x){
	if(ch[x]){
		toch(x<<1,ch[x]);
		toch(x<<1|1,ch[x]);
		ch[x]=0;
	}
}
void change(int x,int y,int z,int l,int r,int cv){
	if(y==l&&z==r){
		toch(x,cv);
		return ;
	}
	pd(x);
	int mid=y+z>>1;
	if(r<=mid){
		change(x<<1,y,mid,l,r,cv);
	}else if(l>mid){
		change(x<<1|1,mid+1,z,l,r,cv);
	}else{
		change(x<<1,y,mid,l,mid,cv);
		change(x<<1|1,mid+1,z,mid+1,r,cv);
	}
}
int ask(int x,int y,int z,int p){
	if(y==z){
		return ch[x];
	}
	pd(x);
	int mid=y+z>>1;
	if(p<=mid){
		return ask(x<<1,y,mid,p);
	}else{
		return ask(x<<1|1,mid+1,z,p);
	}
}
int main(){
	int i,x,y;
	char o[2];
	scanf("%d%d",&n,&m);
	for(i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		be(x,y);
	}
	dep[1]=1;
	dfs(1);
	change(1,1,n,1,n,1);
	for(i=1;i<=m;i++){
		scanf("%s%d",o,&x);
		if(o[0]=='Q'){
			printf("%d\n",ask(1,1,n,dfn[x]));
		}else{
			change(1,1,n,dfn[x],dfn[x]+siz[x]-1,x);
		}
	}
	return 0;
}

/*
4 4
1 2
2 3
3 4
Q 3
C 2
C 1
Q 3


*/


你可能感兴趣的:(BZOJ4551 [Tjoi2016&Heoi2016]树)