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