Pagini recente » Cod sursa (job #1852856) | Cod sursa (job #2491440) | Cod sursa (job #1885989) | Cod sursa (job #167079) | Cod sursa (job #3266564)
#include <fstream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
ifstream cin("stramosi.in");
ofstream cout("stramosi.out");
struct Info {
int node;
int lvl;
Info() = default;
Info(int node, int lvl) : node(node), lvl(lvl) {}
bool operator<(Info a2) const {
return lvl < a2.lvl;
}
};
int n, q;
vector<vector<int>> graph, rev_graph;
vector<int> heads, sz_subtree, node_color, lvl_node_in_path;
vector<set<Info>> heavy;
void read() {
cin >> n >> q;
graph.resize(n + 1);
rev_graph.resize(n + 1);
for (int i = 1; i <= n; i++) {
int val;
cin >> val;
if (val == 0) {
heads.emplace_back(i);
}
graph[val].emplace_back(i);
rev_graph[i].emplace_back(val);
}
}
void dfs1(int node, int par) {
for (auto it : graph[node]) {
dfs1(it, node);
sz_subtree[node] += sz_subtree[it];
}
}
void dfs2(int node, int &color, int lvl) {
lvl_node_in_path[node] = lvl;
node_color[node] = color;
heavy[color].insert(Info(node, lvl));
if (!graph[node].empty()) {
dfs2(graph[node][0], color, lvl + 1);
}
for (int i = 1; i < (int)graph[node].size(); i++) {
color ++;
heavy.emplace_back(set<Info>());
dfs2(graph[node][i], color, 1);
}
}
void solve() {
sz_subtree.resize(n + 1, 1);
for (auto it : heads) {
dfs1(it, 0);
}
for (int i = 1; i <= n; i++) {
sort(graph[i].begin(), graph[i].end(), [](const int a, const int b) -> bool {
return sz_subtree[a] > sz_subtree[b];
});
}
heavy.emplace_back(set<Info>());
node_color.resize(n + 1);
lvl_node_in_path.resize(n + 1);
int color = 1;
for (auto it : heads) {
heavy.emplace_back(set<Info>());
dfs2(it, color, 1);
color ++;
}
while (q --) {
int a, b;
cin >> a >> b;
Info curr_node = Info(a, lvl_node_in_path[a]);
int rem = b;
while (1) {
if (lvl_node_in_path[curr_node.node] - 1 >= rem) {
curr_node = (*heavy[node_color[curr_node.node]].lower_bound(Info(0, lvl_node_in_path[curr_node.node] - rem)));
break;
}
else {
rem -= lvl_node_in_path[curr_node.node];
Info head_of_path = (*heavy[node_color[curr_node.node]].begin());
if (rev_graph[head_of_path.node][0] == 0) {
curr_node = Info(0, -1);
break;
}
curr_node = Info(rev_graph[head_of_path.node][0], lvl_node_in_path[rev_graph[head_of_path.node][0]]);
}
}
cout << curr_node.node << "\n";
}
}
int main() {
read();
solve();
return 0;
}