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;

}