记录编号 |
406268 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[HZOI 2015]树白黑 |
最终得分 |
100 |
用户昵称 |
AntiLeaf |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.919 s |
提交时间 |
2017-05-18 11:07:43 |
内存使用 |
81.95 MiB |
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=200010,maxm=maxn<<5;
void dfs1(int);
void dfs2(int);
int LCA(int,int);
void build(int,int,int&,int);
void query_sum(int,int,int,int);
int query_kth(int,int,int,int);
int sm[maxm],lc[maxm],rc[maxm],root[maxn],cnt=0;
vector<int>G[maxn];
int p[maxn],d[maxn],dfn[maxn],id[maxn],tim=0,size[maxn],son[maxn],top[maxn];
int n,m,q,lgn=0,s,t,k,tmp;
int main(){
freopen("B_Tree.in","r",stdin);
freopen("B_Tree.out","w",stdout);
scanf("%d%d%d",&n,&m,&q);
for(int i=1,x,y;i<n;i++){
scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
dfs1(1);
dfs2(1);
for(int i=1;i<=m;i++){
scanf("%d",&t);
t=dfn[t];
build(1,n,root[i],root[i-1]);
}
while(q--){
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
if(dfn[x]==1){
k=1;
printf("%d\n",LCA(x,id[query_kth(1,n,root[r],root[l-1])]));
}
else if(dfn[x]==n){
k=r-l+1;
printf("%d\n",LCA(x,id[query_kth(1,n,root[r],root[l-1])]));
}
else{
s=1;
t=dfn[x]-1;
tmp=0;
query_sum(1,n,root[r],root[l-1]);
if(tmp){
k=tmp;
int u=id[query_kth(1,n,root[r],root[l-1])];
if(tmp==r-l+1)printf("%d\n",LCA(x,u));
else{
k=tmp+1;
int v=id[query_kth(1,n,root[r],root[l-1])];
u=LCA(x,u);
v=LCA(x,v);
printf("%d\n",d[u]>d[v]?u:v);
}
}
else{
k=1;
printf("%d\n",LCA(x,id[query_kth(1,n,root[r],root[l-1])]));
}
}
}
return 0;
}
void dfs1(int x){
dfn[x]=++tim;
id[tim]=x;
d[x]=d[p[x]]+1;
size[x]=1;
for(int i=0;i<(int)G[x].size();i++)if(G[x][i]!=p[x]){
p[G[x][i]]=x;
dfs1(G[x][i]);
size[x]+=size[G[x][i]];
if(size[G[x][i]]>size[son[x]])son[x]=G[x][i];
}
}
void dfs2(int x){
top[x]=(x==son[p[x]]?top[p[x]]:x);
for(int i=0;i<(int)G[x].size();i++)if(G[x][i]!=p[x])dfs2(G[x][i]);
}
int LCA(int x,int y){
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]])swap(x,y);
x=p[top[x]];
}
return d[x]<d[y]?x:y;
}
void build(int l,int r,int &rt,int pr){
sm[rt=++cnt]=sm[pr]+1;
if(l==r)return;
lc[rt]=lc[pr];
rc[rt]=rc[pr];
int mid=(l+r)>>1;
if(t<=mid)build(l,mid,lc[rt],lc[pr]);
else build(mid+1,r,rc[rt],rc[pr]);
}
void query_sum(int l,int r,int rt,int pr){
if(!rt&&!pr)return;
if(s<=l&&t>=r){
tmp+=sm[rt]-sm[pr];
return;
}
int mid=(l+r)>>1;
if(s<=mid)query_sum(l,mid,lc[rt],lc[pr]);
if(t>mid)query_sum(mid+1,r,rc[rt],rc[pr]);
}
int query_kth(int l,int r,int rt,int pr){
if(l==r)return l;
int mid=(l+r)>>1;
if(k<=sm[lc[rt]]-sm[lc[pr]])return query_kth(l,mid,lc[rt],lc[pr]);
else{
k-=sm[lc[rt]]-sm[lc[pr]];
return query_kth(mid+1,r,rc[rt],rc[pr]);
}
}