记录编号 390655 评测结果 AAAAAAAAAA
题目名称 2280.[HZOI 2015]树白黑 最终得分 100
用户昵称 AntiLeaf 是否通过 通过
代码语言 C++ 运行时间 1.394 s
提交时间 2017-04-03 17:18:13 内存使用 93.39 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=200010,maxm=maxn<<5;
void bfs();
void add(int,int,int&);
int merge(int,int);
void query(int,int,int);
int sm[maxm]={0},lc[maxm]={0},rc[maxm]={0},root[maxn]={0},cnt=0;
vector<int>G[maxn];
int f[maxn][20]={{0}},d[maxn],q[maxn];
int n,m,k,lgn=0,x,y,s,t,tmp;
int main(){
	freopen("B_Tree.in","r",stdin);
	freopen("B_Tree.out","w",stdout);
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		G[x].push_back(y);
		G[y].push_back(x);
	}
	for(t=1;t<=m;t++){
		scanf("%d",&x);
		add(1,m,root[x]);
	}
	bfs();
	for(int j=1;j<=lgn;j++)for(int i=1;i<=n;i++)f[i][j]=f[f[i][j-1]][j-1];
	
	while(k--){
		scanf("%d%d%d",&s,&t,&x);
		tmp=0;
		query(1,m,root[x]);
		if(tmp)printf("%d\n",x);
		else{
			for(int i=lgn;i>=0;i--)if(f[x][i]){
				tmp=0;
				query(1,m,root[f[x][i]]);
				if(!tmp)x=f[x][i];
			}
			printf("%d\n",f[x][0]);
		}
	}
	return 0;
}
void bfs(){
	int x,head=0,tail=0;
	q[tail++]=1;
	while(head!=tail){
		x=q[head++];//printf("%d\n",x);
		d[x]=d[f[x][0]]+1;
		while((1<<lgn)<d[x])lgn++;
		for(int i=0;i<(int)G[x].size();i++)if(G[x][i]!=f[x][0]){
			f[G[x][i]][0]=x;
			q[tail++]=G[x][i];
		}
	}
	for(int i=tail-1;i;i--)root[f[q[i]][0]]=merge(root[f[q[i]][0]],root[q[i]]);
}
void add(int l,int r,int &rt){
	if(!rt)rt=++cnt;
	sm[rt]++;
	if(l==r)return;
	int mid=(l+r)>>1;
	if(t<=mid)add(l,mid,lc[rt]);
	else add(mid+1,r,rc[rt]);
}
int merge(int x,int y){
	if(!x)return y;
	if(!y)return x;
	int rt=++cnt;
	sm[rt]=sm[x]+sm[y];
	lc[rt]=merge(lc[x],lc[y]);
	rc[rt]=merge(rc[x],rc[y]);
	return rt;
}
void query(int l,int r,int rt){
	if(!rt)return;
	if(s<=l&&t>=r){
		tmp+=sm[rt];
		return;
	}
	int mid=(l+r)>>1;
	if(s<=mid)query(l,mid,lc[rt]);
	if(t>mid)query(mid+1,r,rc[rt]);
}