Cod sursa(job #3193072)

Utilizator Allie28Radu Alesia Allie28 Data 13 ianuarie 2024 22:32:15
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.28 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

const int LMAX = 100005;

vector<int> euler, L[LMAX];
int rmq[2 * LMAX][22], depth[LMAX], firstpoz[LMAX], log[2*LMAX];
///rmq[i][j] este nodul cu depth-ul minim din intervalul [i, i + 2^j - 1]
void dfs(int node) {
    euler.push_back(node);
    firstpoz[node] = euler.size() - 1;
    for (int vec : L[node]) {
        depth[vec] = depth[node] + 1;
        dfs(vec);
        euler.push_back(node);
    }
}

void init(int n) {
    for (int i = 2; i < n; i++) {
        log[i] = log[(i>>1)] + 1;
    }
}

int main() {
    int n, m, i, x, j;
    fin>>n>>m;
    for (i = 2; i <= n; i++) {
        fin>>x;
        L[x].push_back(i);
    }
    dfs(1);
    for (i = 0; i < euler.size(); i++) {
        rmq[i][0] = euler[i];
    }
    for (j = 1; j < 22; j++) {
        for (i = 0; i < euler.size(); i++) {
            if (i + (1<<(j-1)) < euler.size()) {
                if (depth[rmq[i][j-1]] > depth[rmq[i + (1<<(j-1))][j-1]]) {
                    rmq[i][j] = rmq[i + (1<<(j-1))][j-1];
                }
                else rmq[i][j] = rmq[i][j-1];
            }
            else {
                rmq[i][j] = 1;
            }
        }
    }
    /*for (i = 0; i < euler.size(); i++) {
        fout<<euler[i]<<" ";
    }
    fout<<endl;
    for (i = 0; i < n; i++) {
        fout<<depth[i]<<" "<<i<<endl;
    }
    fout<<endl;
    fout<<firstpoz[9]<<endl;
    for (j = 0; j < 22; j++) fout<<rmq[7][j]<<" ";
    fout<<endl;
    fout<<firstpoz[14]<<endl;
    for (j = 0; j < 22; j++) fout<<rmq[firstpoz[14]][j]<<" ";
    fout<<endl;*/
    init(euler.size());
    //fout<<rmq[5][4]<<" "<<rmq[7][4]<<endl;
    int y, pmax, dif;
    while (m--) {
        fin>>x>>y;
        if (firstpoz[x] > firstpoz[y]) swap(x, y);
        pmax = log[firstpoz[y] - firstpoz[x] + 1];
//        dif = firstpoz[y] - firstpoz[x] - (1<<pmax);
        if (depth[rmq[firstpoz[x]][pmax]] < depth[rmq[firstpoz[y] - (1<<pmax) + 1][pmax]]) {
            fout<<rmq[firstpoz[x]][pmax];
        }
        else fout<<rmq[firstpoz[y] - (1<<pmax) + 1][pmax];
        fout<<endl;
    }



    fin.close();
    fout.close();
    return 0;
}