Cod sursa(job #2926259)

Utilizator Theodor17Pirnog Theodor Ioan Theodor17 Data 17 octombrie 2022 16:03:29
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.63 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream cin("lca.in");
ofstream cout("lca.out");

const int NMAX = 1e5;
int r[21][2 * NMAX + 1], e[2 * NMAX + 1], t[NMAX + 1], poz[NMAX + 1], nivel[NMAX + 1], lg2[2 * NMAX + 1], n, q, ne;
vector <int> fii[NMAX + 1];

void dfs(int x){

    e[++ne] = x;
    poz[x] = ne;

    for(auto y : fii[x]){

        nivel[y] = 1 + nivel[x];
        dfs(y);

        e[++ne] = x;

    }


}

void rmq(){

    lg2[0] = -1;
    for(int i = 1; i <= ne; i++){

        lg2[i] = 1 + lg2[i >> 1];
        r[0][i] = e[i];

    }

    for(int i = 1; (1 << i) <= ne; i++){
        for(int j = (1 << i); j <= ne; j++){

            r[i][j] = r[i - 1][j];
            int p = (1 << (i - 1));

            if(nivel[r[i - 1][j - p]] < nivel[r[i - 1][j]])
                r[i][j] = r[i - 1][j - p];

        }
    }

}

int lca(int x, int y){

    int st = poz[x], dr = poz[y];
    if(st > dr)
        swap(st, dr);

    int l = lg2[dr - st + 1];
    int p = (1 << l);

    x = r[l][st + p - 1];
    y = r[l][dr];

    if(nivel[x] > nivel[y])
        x = y;

    return x;
}

int main(){

    ios :: sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    cin >> n >> q;

    int start = 0;
    for(int i = 1; i <= n; i++){

        cin >> t[i];

        fii[t[i]].push_back(i);

        if(t[i] == 0)
            start = i;

    }


    dfs(start);
    rmq();

    int x1 = 0, x2 = 0;

    for(int i = 0; i < q; i++){

        cin >> x1 >> x2;
        cout << lca(x1, x2) << "\n";

    }


    return 0;

}