Cod sursa(job #3194924)

Utilizator AdrianRosuRosu Adrian Andrei AdrianRosu Data 19 ianuarie 2024 19:13:04
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.94 kb
#include <bits/stdc++.h>
#define DIM 200001
#define log yhgfrty

using namespace std;

ifstream fin("lca.in");

ofstream fout("lca.out");

vector <int> G[DIM];

struct elem{

    int value, node;

};

elem RMQ[20][DIM];

int euler[DIM], found[DIM], depth[DIM], father[DIM], start[DIM], finish[DIM], log[DIM];

int n, Q, x, i, j, y;

void dfs(int node){

    euler[++euler[0]] = node;

    found[node] = euler[0];

    depth[node] = depth[father[node]] + 1;

    for(vector <int> :: iterator k = G[node].begin() ; k != G[node].end() ; k++)

        if(!found[*k])

            dfs(*k);

    euler[++euler[0]] = father[node];

}

int LCA(int x, int y){

    int pos_x, pos_y;

    pos_x = found[x];

    pos_y = found[y];

    if(pos_x > pos_y)

        swap(pos_x, pos_y);

    int len = log[pos_y - pos_x + 1];

    if(RMQ[len][pos_x].value <= RMQ[len][pos_y - (1LL << len) + 1].value)

        return RMQ[len][pos_x].node;

    return RMQ[len][pos_y - (1LL << len) + 1].node;

}

int main(){

    fin >> n >> Q;

    for(i=2;i<=n;i++){

        fin >> x;

        G[x].push_back(i);

        G[i].push_back(x);

        father[i] = x;

    }

    dfs(1);

    euler[0]--;

    for(i=1;i<=euler[0];i++)

        finish[euler[i]] = i;

    for(i=euler[0];i>=1;i--)

        start[euler[i]] = i;

    for(i=1;i<=euler[0];i++){

        RMQ[0][i].node = euler[i];

        RMQ[0][i].value = depth[euler[i]];

    }

    for(i = 1 ; (1LL << i) <= euler[0] ; i++){

        for(j=1;j<=euler[0];j++){

            int k = j + (1LL << (i - 1));

            RMQ[i][j] = RMQ[i - 1][j];

            if(k <= euler[0] && RMQ[i][j].value > RMQ[i - 1][k].value)

                RMQ[i][j] = RMQ[i - 1][k];

        }

    }

    for(i=2;i<=n;i++)

        log[i] = log[i / 2] + 1;

    while(Q--){

        fin >> x >> y;

        fout << LCA(x, y) << "\n";

    }

}