1466. Ancestor extreme values
Time Limit: 5000 MS Memory Limit: 131072 K
Total Submissions: 153 (39 users) Accepted: 43 (25 users)
[My Solution]
Description
In a directed tree, if a directed edge exists between node u and node v, u is the parent node of v, or 1 ancestor node. The so-called node v k ancestor node refers to the node v parent node of the K-1 ancestor node. Now, given that you have a tree with 0 as the root node, each node in the tree has a value, you need to be able to quickly answer all the nodes from node v to its k-ancestor node (that is, the 1 ancestor of node v and node v ,..., v node of the K-1 ancestor, v node k ancestor), the maximum value of the node value is how many? The default value of node 0 is 0.
Input
The first line of the input has a positive integer n (n <= 100,000), and the next line has n integers ai (1 <= I <= n, 1 <= ai <= 1,000,000,000), the I number represents the value on the I node. The next row contains n positive integers (1 <= I <= n, 0 <= bi <I ), the number I represents the bi of the parent node of node I. Next there is an integer m (1 <= m <= 100,000), which represents the number of queries. In the next m row, each row has two integers k, v (1 <= k <= n, 1 <= v <= n) represents the maximum value among all the nodes that the k ancestor of the v node experiences.
Output
For each query, if the v node does not have a k ancestor, a "Wrong request" line is output; otherwise, an integer is output, represents the maximum value of all the nodes from the v node to its k ancestor.
Sample Input
5
1 2 2 1 3
0 0 1 1 2
4
1 4
2 2
2 3
1 5
Sample Output
1
Wrong request
2
3
Alas, I am so stupid that I can only do it after reading other people's code. It is to use the height of the tree as the interval query.
Sister's, hard-pressed debugging
[Cpp]
# Include <iostream>
# Include <cstdio>
# Include <cstring>
# Include <algorithm>
# Include <vector>
Using namespace std;
# Define N 100010
# Define l (I) I <1
# Define r (I) I <1 | 1
Struct node {
Int l, r, mx;
} T [N * 4];
Int mx;
Struct Data {
Int x, id;
};
Int v [N], ans [N]; // value, answer
Vector <Data> a [N];
Vector <int> son [N];
Void build (int l, int r, int k ){
T [k]. l = l;
T [k]. r = r;
T [k]. mx = 0;
If (l = r) return;
Int mid = (l + r)/2;
Build (l, mid, l (k ));
Build (mid + 1, r, r (k ));
}
Int insert (int d, int k, int v) {// value k insert interval [d, d]
If (T [k]. l = T [k]. r) return T [k]. mx = v;
Int ll = l (k );
Int rr = r (k );
If (T [ll]. r> = d) insert (d, ll, v); // left
Else if (T [rr]. l <= d) insert (d, rr, v); // to the right
Return T [k]. mx = max (T [ll]. mx, T [rr]. mx );
}
Void query (int l, int r, int k) {// query interval [l, r]
If (T [k]. l = l & T [k]. r = r ){
Mx = max (mx, T [k]. mx );
Return;
}
Int ll = l (k );
Int rr = r (k );
If (T [ll]. r> = r) query (l, r, ll); // left
Else if (T [rr]. l <= l) query (l, r, rr); // to the right
Else {
Query (l, T [ll]. r, ll); // left
Query (T [rr]. l, r, rr); // forward to the right
}
}
Void dfs (int x, int d ){
Int I, j, k;
Insert (d, 1, v [x]); // insert v
// Cout <"insert" <x <"" <v [x] <endl;
For (I = 0; I <a [x]. size (); I ++) {// query x Nodes
K = d-a [x] [I]. x;
Mx =-1;
If (k> = 0) query (k, d, 1 );
Ans [a [x] [I]. id] = mx;
// Cout <x <"<k <" "<d <" "<mx <endl;
}
For (I = 0; I <son [x]. size (); I ++) // traverse the son
Dfs (son [x] [I], d + 1); // recursive Traversal
}
Int main (){
Int n, I, j, k;
V [0] = 0;
Struct Data s;
While (scanf ("% d", & n )! = EOF ){
Memset (a, 0, sizeof ());
Memset (son, 0, sizeof (son ));
Build (0, n-1, 1); // create an empty tree
For (I = 1; I <= n; I ++) scanf ("% d", & v [I]);
For (I = 1; I <= n; I ++ ){
Scanf ("% d", & j );
Son [j]. push_back (I); // I is the son of j.
}
Scanf ("% d", & n );
For (I = 0; I <n; I ++ ){
Scanf ("% d", & j, & k );
S. x = j; s. id = I;
A [k]. push_back (s );
}
/* For (I = 0; I <= n; I ++ ){
Cout <I <":";
For (j = 0; j <son [I]. size (); j ++ ){
Cout <son [I] [j] <"";
}
Cout <endl;
}*/
Dfs (); // traverse from the root to the end
For (I = 0; I <n; I ++)
If (ans [I] =-1) printf ("Wrong request \ n ");
Else printf ("% d \ n", ans [I]);
}
Return 0;
}
# Include <iostream>
# Include <cstdio>
# Include <cstring>
# Include <algorithm>
# Include <vector>
Using namespace std;
# Define N 100010
# Define l (I) I <1
# Define r (I) I <1 | 1
Struct node {
Int l, r, mx;
} T [N * 4];
Int mx;
Struct Data {
Int x, id;
};
Int v [N], ans [N]; // value, answer
Vector <Data> a [N];
Vector <int> son [N];
Void build (int l, int r, int k ){
T [k]. l = l;
T [k]. r = r;
T [k]. mx = 0;
If (l = r) return;
Int mid = (l + r)/2;
Build (l, mid, l (k ));
Build (mid + 1, r, r (k ));
}
Int insert (int d, int k, int v) {// value k insert interval [d, d]
If (T [k]. l = T [k]. r) return T [k]. mx = v;
Int ll = l (k );
Int rr = r (k );
If (T [ll]. r> = d) insert (d, ll, v); // left
Else if (T [rr]. l <= d) insert (d, rr, v); // to the right
Return T [k]. mx = max (T [ll]. mx, T [rr]. mx );
}
Void query (int l, int r, int k) {// query interval [l, r]
If (T [k]. l = l & T [k]. r = r ){
Mx = max (mx, T [k]. mx );
Return;
}
Int ll = l (k );
Int rr = r (k );
If (T [ll]. r> = r) query (l, r, ll); // left
Else if (T [rr]. l <= l) query (l, r, rr); // to the right
Else {
Query (l, T [ll]. r, ll); // left
Query (T [rr]. l, r, rr); // forward to the right
}
}
Void dfs (int x, int d ){
Int I, j, k;
Insert (d, 1, v [x]); // insert v
// Cout <"insert" <x <"" <v [x] <endl;
For (I = 0; I <a [x]. size (); I ++) {// query x Nodes
K = d-a [x] [I]. x;
Mx =-1;
If (k> = 0) query (k, d, 1 );
Ans [a [x] [I]. id] = mx;
// Cout <x <"<k <" "<d <" "<mx <endl;
}
For (I = 0; I <son [x]. size (); I ++) // traverse the son
Dfs (son [x] [I], d + 1); // recursive Traversal
}
Int main (){
Int n, I, j, k;
V [0] = 0;
Struct Data s;
While (scanf ("% d", & n )! = EOF ){
Memset (a, 0, sizeof ());
Memset (son, 0, sizeof (son ));
Build (0, n-1, 1); // create an empty tree
For (I = 1; I <= n; I ++) scanf ("% d", & v [I]);
For (I = 1; I <= n; I ++ ){
Scanf ("% d", & j );
Son [j]. push_back (I); // I is the son of j.
}
Scanf ("% d", & n );
For (I = 0; I <n; I ++ ){
Scanf ("% d", & j, & k );
S. x = j; s. id = I;
A [k]. push_back (s );
}
/* For (I = 0; I <= n; I ++ ){
Cout <I <":";
For (j = 0; j <son [I]. size (); j ++ ){
Cout <son [I] [j] <"";
}
Cout <endl;
}*/
Dfs (); // traverse from the root to the end
For (I = 0; I <n; I ++)
If (ans [I] =-1) printf ("Wrong request \ n ");
Else printf ("% d \ n", ans [I]);
}
Return 0;
}