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
题目大意 给定一棵树,每个点有两个权值,忠诚度和能力值,每次询问点x的子树中能力值大于它,忠诚度最高的一位的编号。
Solution 1 树分块
因为查询的时候,查询一个节点的子树实际上是等于查询一段区间内的数据,所以考虑对dfs序进行分块。
按照dfs序进行分块,块内按忠诚度进行排序,再记录后缀忠诚度最大值。
根据常用套路,每次查询,对于块两端部分,暴力for。中间每个块lower_bound upper_bound一下查询合法的一段,然后用后缀忠诚度最大值进行更新答案就好了。
(这是我比较笨的分块方法)
设块的大小为s,块的数量为c,则总时间复杂度为
Code
1 /** 2 * hdu 3 * Problem#4366 4 * Accepted 5 * Time: 748ms 6 * Memory: 8468k 7 */ 8 #include <bits/stdc++.h> 9 using namespace std; 10 typedef bool boolean; 11 12 typedef class Staff { 13 public: 14 int loy; 15 int abi; 16 int id; 17 18 boolean operator < (Staff b) const { 19 if(abi != b.abi) return abi < b.abi; 20 return loy < b.loy; 21 } 22 }Staff; 23 24 boolean operator < (const int& x, const Staff& s) { 25 return x < s.abi; 26 } 27 28 const int maxcsize = 300; 29 typedef class Chunk { 30 public: 31 int len; 32 Staff sta[maxcsize]; 33 int maxv[maxcsize]; 34 int ans[maxcsize]; 35 36 void init(Staff* lis, int from, int end) { 37 len = end - from; 38 for(int i = from; i < end; i++) 39 sta[i - from] = lis[i]; 40 sort(sta, sta + len); 41 maxv[len] = -1; 42 ans[len] = -1; 43 for(int i = len - 1; i >= 0; i--) { 44 if(sta[i].loy > maxv[i + 1]) 45 maxv[i] = sta[i].loy, ans[i] = sta[i].id; 46 else 47 maxv[i] = maxv[i + 1], ans[i] = ans[i + 1]; 48 } 49 } 50 51 void getAns(int limit, int& rmaxv, int& rans) { 52 int pos = upper_bound(sta, sta + len, limit) - sta; 53 if(maxv[pos] > rmaxv) 54 rmaxv = maxv[pos], rans = ans[pos]; 55 } 56 }Chunk; 57 58 int n, m; 59 int cs, cc; 60 vector<int> *g; 61 Staff lis[50005]; 62 Staff *nlis; 63 Chunk chs[300]; 64 65 inline void init() { 66 scanf("%d%d", &n, &m); 67 g = new vector<int>[(n + 1)]; 68 nlis = new Staff[(n + 1)]; 69 for(int i = 1, x; i < n; i++) { 70 scanf("%d%d%d", &x, &lis[i].loy, &lis[i].abi); 71 lis[i].id = i; 72 g[x].push_back(i); 73 } 74 lis[0].loy = lis[0].abi = 23333333; 75 lis[0].id = 0; 76 cs = sqrt(n + 0.5); 77 } 78 79 int cnt; 80 int visitID[50005], exitID[50005]; 81 int visit[50005]; 82 inline void dfs(int node) { 83 visitID[node] = ++cnt; 84 visit[cnt] = node; 85 for(int i = 0; i < (signed)g[node].size(); i++) 86 dfs(g[node][i]); 87 exitID[node] = cnt; 88 } 89 90 inline void init_chunks() { 91 for(int i = 1; i <= n; i++) 92 nlis[i] = lis[visit[i]], nlis[i].id = i; 93 for(cc = 0; cc * cs < n; cc++) 94 chs[cc + 1].init(nlis, cc * cs + 1, min((cc + 1) * cs, n) + 1); 95 } 96 97 inline void solve() { 98 int l, r, x, maxv, ans, lim; 99 while(m--) { 100 scanf("%d", &x); 101 maxv = -1, ans = -1; 102 l = visitID[x], r = exitID[x], lim = lis[x].abi; 103 int lid = l / cs + 1, rid = r / cs + 1; 104 if(lid == rid) { 105 for(int i = l; i <= r; i++) 106 if(nlis[i].abi > lim && nlis[i].loy > maxv) 107 maxv = nlis[i].loy, ans = i; 108 } else { 109 // if(x == 992) 110 // putchar('a'); 111 for(int i = l; i <= lid * cs; i++) 112 if(nlis[i].abi > lim && nlis[i].loy > maxv) 113 maxv = nlis[i].loy, ans = i; 114 for(int i = (rid - 1) * cs + 1; i <= r; i++) 115 if(nlis[i].abi > lim && nlis[i].loy > maxv) 116 maxv = nlis[i].loy, ans = i; 117 for(int i = lid + 1; i < rid; i++) 118 chs[i].getAns(lim, maxv, ans); 119 } 120 printf("%d\n", (ans == -1) ? (-1) : (visit[ans])); 121 } 122 } 123 124 inline void clear() { 125 delete[] g; 126 delete[] nlis; 127 } 128 129 int T; 130 int main() { 131 // freopen("a.in", "r", stdin); 132 // freopen("a.out", "w", stdout); 133 scanf("%d", &T); 134 while(T--) { 135 init(); 136 cnt = 0; 137 dfs(0); 138 init_chunks(); 139 solve(); 140 clear(); 141 } 142 // fprintf(stderr, "Time: %dms\n", clock()); 143 return 0; 144 }