线段树
题意: 每个员工有一个上级,每个上级有很多下级,求fire掉一个人之后可以用哪个人顶上
/*
线段树
题意: 每个员工有一个上级,每个上级有很多下级,求fire掉一个人之后可以用哪个人顶上
替换规则:该员工的能力比他高的下级中, loyalty最大的那个,如果没有,则输出 -1
思路:员工的上下级关系应该是一棵树,dfs,dfs次序对应转化为一维之后的下标{[()]},就像这样;
一棵子树的结点对应成线段上的点总是连续的,我们记录开始结点ll,跟结束结点rr;
那么求该子树根节点用哪个替换就转化成求[ll,rr]区间上,ability比根节点大的中loyalty最大的;
将结点按ability按从大到小排序,然后一个个依次加入线段树中,这样就能保证在当前结点加入前,线段树
中结点的ability都是比它大的,先求该节点的[ll,rr]区间内loyalty最大的,然后加入该节点
线段树要维护的就是最大的loyalty,又因loyalty是唯一的,所以可以对应员工编号
*/
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdlib>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define N 50005
#include<map>
using namespace std;
int Max[N<<2],ans[N],head[N],ll[N],rr[N],p[N];
int cnt;
map<int,int > mp;
struct person{
int l,a,no;
}num[N];
struct edge{
int v,next;
}e[N];
bool cmp(const person x,person y){
if(x.a!=y.a)
return x.a>y.a;
return x.no<y.no;
}
void init(){
cnt=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v){
e[cnt].v=v;e[cnt].next=head[u];head[u]=cnt++;
}
void dfs(int x){
p[x]=cnt;
ll[x]=cnt;
for(int i=head[x];i!=-1;i=e[i].next){
cnt++;
dfs(e[i].v);
}
rr[x]=cnt;
}
void pushup(int rt){
Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
}
void build(int l,int r,int rt){
Max[rt]=0;
if(l==r){
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
}
int query(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
return Max[rt];
}
int m=(l+r)>>1;
if(R<=m)
return query(L,R,lson);
if(L>m)
return query(L,R,rson);
return max(query(L,R,lson),query(L,R,rson));
}
void update(int x,int i,int l,int r,int rt){
// cout<<p[x]<<' '<<i<<' '<<l<<' '<<r<<' '<<rt<<endl;
if(l==r){
Max[rt]=num[i].l;
return ;
}
int m=(l+r)>>1;
if(p[x]<=m)
update(x,i,lson);
else
update(x,i,rson);
pushup(rt);
}
int main()
{
int T,n,m,j,x;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
init();
for(int i=2;i<=n;i++){
scanf("%d",&j);
num[i].no=i;
scanf("%d%d",&num[i].l,&num[i].a);
mp[num[i].l] = i;
addedge(j+1,i);
}
cnt=1;
dfs(1);
build(1,n,1);
sort(num+2,num+1+n,cmp);
for(int i=2;i<=n;i++){
ans[num[i].no]=query(ll[num[i].no],rr[num[i].no],1,n,1);
if(ans[num[i].no]!=0){
ans[num[i].no]=mp[ans[num[i].no]];
}
update(num[i].no,i,1,n,1);
}
while(m--){
scanf("%d",&x);
printf("%d\n",ans[x+1]-1);
}
}
return 0;
}