Successor
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 3880 Accepted Submission(s): 917
Problem Description
Sean owns a company and he is the BOSS.The other Staff has one Superior.every staff has a loyalty and ability.Some times Sean will fire one staff.Then one of the fired man’s Subordinates will replace him whose ability is higher than him and has the highest loyalty for company.Sean want to know who will replace the fired man.
Input
In the first line a number T indicate the number of test cases. Then for each case the first line contain 2 numbers n,m (2<=n,m<=50000),indicate the company has n person include Sean ,m is the times of Sean’s query.Staffs are numbered from 1 to n-1,Sean’s number is 0.Follow n-1 lines,the i-th(1<=i<=n-1) line contains 3 integers a,b,c(0<=a<=n-1,0<=b,c<=1000000),indicate the i-th staff’s superior Serial number,i-th staff’s loyalty and ability.Every staff ‘s Serial number is bigger than his superior,Each staff has different loyalty.then follows m lines of queries.Each line only a number indicate the Serial number of whom should be fired.
Output
For every query print a number:the Serial number of whom would replace the losing job man,If there has no one to replace him,print -1.
Sample Input
1 3 2 0 100 99 1 101 100 1 2
Sample Output
2 -1
题意:给一棵树,每个节点有a,l两个值,每次询问一个节点的子树中a值比他大并且
l值最大的节点。
先把按照dfs序所有的节点放到线段树中,线段树只需要维护b值的最大值。然后节点
按照a值从小到大,b从大到小排序,扫描一遍,每次查询最大,删除这个节点。
#include <bits/stdc++.h>
using namespace std;
#define pl c<<1
#define pr (c<<1)|1
#define lson tree[c].l,tree[c].mid,pl
#define rson tree[c].mid+1,tree[c].r,pr
#define maxn 51111
#define INF 1111111
struct node {
int l, r, mid;
int Max;
}tree[maxn<<4];
int n, m;
struct one {
int a, l, id;
bool operator < (const one &aa) const {
return a < aa.a || (a == aa.a && l >= aa.l);
}
}p[maxn];
struct E {
int v, next;
}edge[maxn<<1];
int head[maxn], cnt;
void add_edge (int u, int v) { //cout << u << " " << v << endl;
edge[cnt].v = v, edge[cnt].next = head[u], head[u] = cnt++;
}
int dfs_clock;
int l[maxn], r[maxn], gg[maxn];
void dfs (int u) { //cout << u << endl;
l[u] = INF;
for (int i = head[u]; i != -1; i = edge[i].next) {
int v = edge[i].v;
dfs (v);
l[u] = min (l[u], l[v]);
}
r[u] = ++dfs_clock;
l[u] = min (l[u], r[u]);
}
void push_up (int c) {
if (tree[c].l == tree[c].r)
return ;
tree[c].Max = max (tree[pl].Max, tree[pr].Max);
}
void build_tree (int l, int r, int c) {
tree[c].l = l, tree[c].r = r, tree[c].mid = (l+r)>>1;
if (l == r) {
tree[c].Max = p[gg[l]].l;
return ;
}
build_tree (lson);
build_tree (rson);
push_up (c);
}
int query (int l, int r, int c, int x, int y) {.Max << endl;
if (y < x) return -1;
if (l == x && y == r) {
return tree[c].Max;
}
if (tree[c].mid >= y) {
return query (lson, x, y);
}
else if (tree[c].mid < x) {
return query (rson, x, y);
}
else {
return max (query (lson, x, tree[c].mid), query (rson, tree[c].mid+1, y));
}
}
void update (int l, int r, int c, int pos) {
if (l == r) {
tree[c].Max = -1;
return ;
}
if (pos <= tree[c].mid)
update (lson, pos);
else
update (rson, pos);
push_up (c);
}
int ans[maxn];
struct pp {
int num, pos;
bool operator < (const pp &a) const {
return num < a.num;
}
};
vector <pp> vec;
int main () {
int t;
scanf ("%d", &t);
while (t--) {
scanf ("%d%d", &n, &m);
memset (head, -1, sizeof head);
cnt = dfs_clock = 0;
vec.clear ();
n--;
for (int i = 1; i <= n; i++) {
int u, a, l;
scanf ("%d%d%d", &u, &l, &a);
add_edge (u, i);
vec.push_back ((pp) {l, i});
p[i].l = l, p[i].a = a; p[i].id = i;
}
dfs (0);
for (int i = 1; i <= n; i++) gg[r[i]] = i;
build_tree (1, n, 1);
sort (p+1, p+1+n);
sort (vec.begin (), vec.end ());
for (int i = 1; i <= n; i++) {
int u = p[i].id;
ans[u] = query (1, n, 1, l[u], r[u]-1);
update (1, n, 1, r[u]);
if (ans[u] != -1) {
int id = lower_bound (vec.begin (), vec.end (), (pp) {ans[u], 0})-vec.begin ();
ans[u] = vec[id].pos;
}
}
while (m--) {
int u;
scanf ("%d", &u);
printf ("%d\n", ans[u]);
}
}
return 0;
}