Cod sursa(job #2604842)

Utilizator CosminMorarMorar Cosmin Andrei CosminMorar Data 23 aprilie 2020 17:13:36
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.69 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, q, euler[200010], depth[200010], pos, rmq[18][100010], lg[100010], len, first_occ[100010];
vector<int> nod[100010];

void gen_euler_repres(int act, int act_depth) {
    euler[++pos] = act;
    depth[pos] = act_depth;

    if (!first_occ[act])
        first_occ[act] = pos;

    for (int fiu : nod[act]) {
        gen_euler_repres(fiu, act_depth + 1);
        euler[++pos] = act;
        depth[pos] = act_depth;
    }
}

int main() {
    fin >> n >> q;
    for (int i = 2; i <= n; i++) {
        int nr;
        fin >> nr;
        nod[nr].push_back(i);
    }

    gen_euler_repres(1, 0);

    /// RMQ FOR DEPTHS
    len = 2 * n - 1;

    for (int i = 2; i <= len; i++)
        lg[i] = lg[i / 2] + 1;

    for (int i = 1; i <= len; i++)
        rmq[0][i] = i;

    for (int p = 1; 1 << p <= len; p++)
        for (int i = 1; i + (1 << p) - 1 <= len; i++) {
            int rmq1 = rmq[p - 1][i];
            int rmq2 = rmq[p - 1][i + (1 << (p - 1))];

            if (depth[rmq1] < depth[rmq2])
                rmq[p][i] = rmq1;
            else
                rmq[p][i] = rmq2;
        }

    /// ANSWERING QUERIES
    while (q--) {
        int a, b;
        fin >> a >> b;

        a = first_occ[a];
        b = first_occ[b];

        if (a > b)
            swap(a, b);

        int dif = b - a + 1;
        int rmqa = rmq[lg[dif]][a];
        int rmqb = rmq[lg[dif]][b - (1 << lg[dif]) + 1];

        if (depth[rmqa] < depth[rmqb])
            fout << euler[rmqa] << '\n';
        else
            fout << euler[rmqb] << '\n';
    }
    return 0;
}