Cod sursa(job #2635199)

Utilizator paul3ioanCirstean Paul Ioan paul3ioan Data 13 iulie 2020 17:05:54
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.69 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
int n ,q, viz[100001];
int v[100001], k, a;
int rmq[200001][20];
int euler[200001], nivel[200001], poz[100001];
vector <int> L[100001];
void  dfs(int x)
{
    a++;
    viz[x] = 1;
    euler[++k] = x;
    nivel[k] = a;
    if(!poz[x])
        poz[x] = k;
    for(int i : L[x])
    {   if(!viz[i])
        {
            dfs(i);
            euler[++k] = x;
            nivel[k] = a;
        }
    }
    a--;
}
void prelucrare();
int LCA(int,int);
int queryRMQ(int i ,int j)
{
    int length = j - i + 1;
    int log = 0;
    while( (1<<(log + 1)) <= length)
        log++;
    if(nivel[rmq[i][log]] < nivel[rmq[j - (1<< log) + 1][log]])
        return euler[rmq[i][log]];
    else
        return euler[rmq[j -(1 << log) + 1][log]];
}
int main() {
    cin >> n >> q;
    for(int i =2;i <= n ;i ++)
    {
        cin >> v[i];
        L[i].push_back(v[i]);
        L[v[i]].push_back(i);
    }
    dfs(1);
    prelucrare();
    int x, y;
    while(q--)
    {
        cin >> x >> y;
        cout << LCA(x,y)<<'\n';
    }
//    for(int i = 1 ;i <=k ;i ++)
//        cout << euler[i] << " " << nivel[i]<<'\n';
    return 0;
}
void prelucrare()
{
    for(int i =1 ;i <= k;  i ++)
        rmq[i][0] = i;
    int log = 0;
    while( (1<<(log + 1)) <= k)
        log++;
    for(int j = 1 ;j <= log; j ++)
    {
        for(int i = 1 ;i<= k - (1<<j) + 1;i ++)
        {
            if(nivel[rmq[i][j - 1]] < nivel[rmq[i + (1<<(j-1)) ][j -1]])
                rmq[i][j] = rmq[i][j - 1];
            else
                rmq[i][j] =rmq[i + (1<<(j-1)) ][j - 1];
        }
    }
}
int LCA(int x, int y)
{
    return queryRMQ(poz[x],poz[y]);
}