题意:
现在n个人,其中编号0的是老板,之后n-1个员工,每个员工只有一个上司,有一个忠诚值和能力值。每次要解雇一个人的时候,从他的下属中选取能力值大于他的且忠诚值最高的一个,若不存在则输出-1.共m次询问,每次询问i,输出解雇i会选择哪个编号的员工代替值。(所有询问都不相互影响)
#include<bits/stdc++.h>
using namespace std;
#define N 50020 struct peo
{
int a,v,id;
peo()
{
a=;v=;id=;
} }s[N];
int t[N<<];
int cnt,n,q;
vector<int>v[N];
int ha[],l[N],r[N],ans[N]; void dfs(int x)
{
l[x]=++cnt;
for(int i=;i<v[x].size();i++)
dfs(v[x][i] );
r[x]=cnt;
} void build(int L,int R,int pos)
{
t[pos]=-;
if(L==R)
return ;
int mid=(L+R)>>;
build(L,mid,pos<< );
build(mid+,R,pos<<|);
} bool cmp(peo a,peo b)
{
return a.a>b.a;
} void update(int x,int v,int L,int R,int pos)
{
if(L==R)
{
t[pos]=v;
return ;
}
int mid=(L+R)>>;
if(x<=mid)
update(x,v,L,mid,pos<<);
else
update(x,v,mid+,R,pos<<|);
t[pos]=max(t[pos<<],t[pos<<|]);
} int query(int l,int r,int L,int R,int pos)
{
int ans=-;
if(l<=L&&r>=R)
return t[pos];
int mid=(L+R)>>;
if(l<=mid)ans=max(ans,query(l,r,L,mid,pos<<));
if(r>mid)ans=max(ans,query(l,r,mid+,R,pos<<|));
return ans;
} int main()
{
int cas;cin>>cas;
while(cas--)
{
scanf("%d%d",&n,&q);
for(int i=;i<n;i++)
v[i].clear(); for(int i=;i<n;i++)
{
int pre;
scanf("%d%d%d",&pre,&s[i].v,&s[i].a);
v[pre].push_back(i);
s[i].id=i;
ha[s[i].v]=i;
}
cnt=;
dfs();
build (,n-,);
sort(s+,s+n,cmp);
int i=,j;
while(i<n)
{
j=i;
while(j<n&&s[i].a==s[j].a)
{
int k=query( l[s[j].id ],r[s[j].id ]-,,n-, );
if(k==-)
ans[s[j].id ]=-;
else
ans[s[j].id]=ha[k];
j++;
}
j=i;
while(j<n&&s[i].a==s[j].a)
{
update(l[s[j].id ]-,s[j].v,,n-, );
j++;
}
i=j;
}
while(q--)
{
int x;
scanf("%d",&x);
printf("%d\n",ans[x]);
}
}
return ;
}