Cod sursa(job #3266562)

Utilizator db_123Balaban David db_123 Data 9 ianuarie 2025 15:31:39
Problema Stramosi Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.72 kb
#include <fstream>
#include <vector>
#include <set>

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 < 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;
}