Cod sursa(job #2929839)

Utilizator Paul281881818818181991919191881818Draghici Paul Paul281881818818181991919191881818 Data 26 octombrie 2022 22:57:57
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.07 kb
#include <fstream>
#include <vector>

using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
inline int Log2(int n){
    int Log2 = 0;
    while(n > 1){
        Log2 ++;
        n /= 2;
    }
    return Log2;
}
int n, m;
const int NMAX = 100002;
vector<int> V[NMAX];
int euler[2*NMAX], cnt, Level[NMAX], First[NMAX];
bool viz[NMAX];
void DFSEuler(int node, int level){
    euler[++cnt] = node;
    Level[cnt] = level;
    First[node] = cnt;
    viz[node] = true;
    for(int i = 0; i < V[node].size(); i++){
        if(!viz[V[node][i]]){
            DFSEuler(V[node][i], level+1);
            euler[++cnt] = node;
            Level[cnt] = level;
        }
    }
}
int RMQ[17][NMAX*2];
void buildRMQ(){
    for(int i = 1; i <= cnt; i++){
        RMQ[0][i] = i; 
    }
    for(int i = 1; i <= Log2(cnt); i++){
        for(int j = 1; j <= cnt-(1<<i); j++){
            if(Level[RMQ[i-1][j]] < Level[RMQ[i-1][j + (1 << (i-1))]]){
                RMQ[i][j] = RMQ[i-1][j];
            }
            else
                RMQ[i][j] = RMQ[i-1][j + (1 << (i-1))];
        }
    }
}

int LCA(int u, int v){
    if(First[u] > First[v]){
        swap(u, v);
    }
    u = First[u];
    v = First[v];
    int DiffLog = Log2(v - u + 1);
    if(Level[RMQ[DiffLog][u]] < Level[RMQ[DiffLog][v - (1 << DiffLog) + 1]]){
        return euler[RMQ[DiffLog][u]];
    }
    return euler[RMQ[DiffLog][v - (1 << DiffLog) + 1]];
}
int main(){
    fin >> n >> m;
    for (int i = 2; i <= n; i++)
    {
        int ancestor_of_i;
        fin >> ancestor_of_i;
        V[ancestor_of_i].push_back(i);
    }
    DFSEuler(1, 0);
    
    buildRMQ();
    /*for(int i=1; i<=cnt; i++){
        fout << Level[i] << " ";
    }
    fout << "\n";
    for(int i=0; i<=Log2(cnt); i++){
        for(int j=1; j<=cnt - (1<<i); j++){
            fout << RMQ[i][j] << " ";
        }
        fout << "\n";
    }*/
    for(int q = 1; q <= m; q++){
        int node1, node2;
        fin >> node1 >> node2;
        fout << LCA(node1, node2) << '\n';
    }
    return 0;
}