#include <bits/stdc++.h>
using namespace std;
/***
Given a rooted tree, you have to support 2 types of operations:
* paint the root of a full black subtree in black
* check where the path from a black node to the root becomes white
I can do the erases using binary lifting:
* if the 2^k ancestor of node u is black, than all the nodes between them are black
* if not, you can go down the tree
Add operation:
* I will always want to add in the same exact order
* So I will have a vector of 1 and 0, and I want to find the LAST 0
***/
const int LG = 17;
const int MAXN = 1000 * 100;
vector<int> g[MAXN + 1], order[MAXN + 1];
int dad[MAXN + 1], minValue[MAXN + 1], who[MAXN + 1], tin[MAXN + 1];
int ancestor[LG + 1][MAXN + 1];
bool black[MAXN + 1];
priority_queue<int> fr;
void dfs(int u) {
vector<pair<int, int>> children;
for (const int &v : g[u]) {
dfs(v);
minValue[u] = min(minValue[u], minValue[v]);
children.emplace_back(minValue[v], v);
}
sort(children.begin(), children.end());
reverse(children.begin(), children.end());
for (const auto &p : children) {
order[u].push_back(p.second);
}
}
void dfsOrder(int u) {
static int t = 0;
tin[u] = t++;
who[t - 1] = u;
for (const int &v : order[u]) {
dfsOrder(v);
}
}
int add() {
int u = who[fr.top()];
fr.pop();
black[u] = true;
return u;
}
int erase(int u) {
int ans = 0;
for (int l = LG; l >= 0; l--) {
if (black[ancestor[l][u]]) {
u = ancestor[l][u];
ans += (1 << l);
}
}
fr.push(tin[u]);
black[u] = false;
return ans;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
int n, q; cin >> n >> q;
int root = -1;
for (int i = 1; i <= n; i++) {
cin >> dad[i];
if (dad[i] != 0) {
g[dad[i]].push_back(i);
} else {
root = i;
}
}
for (int i = 1; i <= n; i++) {
minValue[i] = i;
fr.push(i - 1);
}
dfs(root);
dfsOrder(root);
for (int u = 1; u <= n; u++) {
ancestor[0][u] = dad[u];
}
for (int k = 1; k <= LG; k++) {
for (int u = 1; u <= n; u++) {
ancestor[k][u] = ancestor[k - 1][ancestor[k - 1][u]];
}
}
for (int i = 0; i < q; i++) {
int op, k; cin >> op >> k;
if (op == 1) {
int u = -1;
for (int j = 0; j < k; j++) {
u = add();
}
cout << u << "\n";
} else {
cout << erase(k) << "\n";
}
}
return 0;
}
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
3 ms |
5076 KB |
Output is correct |
2 |
Correct |
73 ms |
13292 KB |
Output is correct |
3 |
Correct |
48 ms |
13380 KB |
Output is correct |
4 |
Correct |
3 ms |
5076 KB |
Output is correct |
5 |
Correct |
2 ms |
5076 KB |
Output is correct |
6 |
Correct |
3 ms |
5204 KB |
Output is correct |
7 |
Correct |
3 ms |
5204 KB |
Output is correct |
8 |
Correct |
3 ms |
5204 KB |
Output is correct |
9 |
Correct |
6 ms |
5588 KB |
Output is correct |
10 |
Correct |
15 ms |
7136 KB |
Output is correct |
11 |
Correct |
101 ms |
13284 KB |
Output is correct |
12 |
Correct |
48 ms |
13380 KB |
Output is correct |
13 |
Correct |
64 ms |
13320 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
29 ms |
10164 KB |
Output is correct |
2 |
Correct |
101 ms |
23672 KB |
Output is correct |
3 |
Correct |
68 ms |
17108 KB |
Output is correct |
4 |
Correct |
43 ms |
10968 KB |
Output is correct |
5 |
Correct |
39 ms |
10724 KB |
Output is correct |
6 |
Correct |
41 ms |
10804 KB |
Output is correct |
7 |
Correct |
40 ms |
9548 KB |
Output is correct |
8 |
Correct |
27 ms |
10160 KB |
Output is correct |
9 |
Correct |
130 ms |
24444 KB |
Output is correct |
10 |
Correct |
99 ms |
23680 KB |
Output is correct |
11 |
Correct |
84 ms |
23628 KB |
Output is correct |
12 |
Correct |
93 ms |
20616 KB |
Output is correct |
13 |
Correct |
70 ms |
28568 KB |
Output is correct |
14 |
Correct |
58 ms |
17144 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
43 ms |
14852 KB |
Output is correct |
2 |
Correct |
128 ms |
21068 KB |
Output is correct |
3 |
Correct |
108 ms |
26396 KB |
Output is correct |
4 |
Correct |
78 ms |
20700 KB |
Output is correct |
5 |
Correct |
67 ms |
20112 KB |
Output is correct |
6 |
Correct |
72 ms |
20028 KB |
Output is correct |
7 |
Correct |
70 ms |
17844 KB |
Output is correct |
8 |
Correct |
93 ms |
26412 KB |
Output is correct |
9 |
Correct |
108 ms |
24648 KB |
Output is correct |
10 |
Correct |
126 ms |
23772 KB |
Output is correct |
11 |
Correct |
127 ms |
23876 KB |
Output is correct |
12 |
Correct |
120 ms |
21016 KB |
Output is correct |
13 |
Correct |
130 ms |
31812 KB |
Output is correct |
14 |
Correct |
105 ms |
17256 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
129 ms |
24760 KB |
Output is correct |
2 |
Correct |
105 ms |
21104 KB |
Output is correct |
3 |
Correct |
78 ms |
31624 KB |
Output is correct |
4 |
Correct |
125 ms |
24820 KB |
Output is correct |
5 |
Correct |
119 ms |
23776 KB |
Output is correct |
6 |
Correct |
103 ms |
23732 KB |
Output is correct |
7 |
Correct |
106 ms |
21016 KB |
Output is correct |
8 |
Correct |
79 ms |
31596 KB |
Output is correct |
9 |
Correct |
66 ms |
17116 KB |
Output is correct |