Cod sursa(job #3207950)

Utilizator AndreasBossGamerBaragau Andreas AndreasBossGamer Data 27 februarie 2024 09:54:52
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.23 kb
#include <fstream>
#include <vector>
const int MAX = 100001;

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

int n, q;
vector<vector<int> > adj;

///lca
bool vizitat[MAX];
int euler[2*MAX];
int height[MAX];
int low[MAX];

///rmq
int rmq[18][2*MAX];
int bitSemnificativ[2*MAX];

void dfs(int node, int& index)
{
    vizitat[node] = true;
    euler[++index] = node;
    for(auto vecin : adj[node])
    {
        if(!vizitat[vecin])
        {
            height[vecin] = height[node] + 1;
            low[vecin] = index + 1;
            dfs(vecin, index);
            euler[++index] = node;
        }
    }
}

int lca(int x, int y)
{
    int st = low[x];
    int dr = low[y];

    if(st > dr) swap(st, dr);

    int e = bitSemnificativ[dr-st+1];
    int len = 1<<e;
    int sol = min(rmq[e][st], rmq[e][dr - len + 1]);

    /*cout<<"NODURILE : x = "<<x<<" si y = "<<y<<'\n';
    cout<<"APARITII MINIME : "<<st<<" "<<dr<<'\n';
    cout<<"LOCATIE EULER "<<sol<<"\n\n";*/

    return sol;
}

int main()
{
    cin>>n>>q;
    adj.resize(n+1);
    for(int i = 2; i <= n;i++)
    {
        int x;
        cin >> x;
        adj[x].push_back(i);
    }

    int index = 0;
    height[1] = 1;
    low[1] = 1;
    dfs(1, index);

    /*cout<<"HEIGHTS :\n";
    for(int i = 1;i<=n;i++) cout<<height[i]<<" ";*/

    ///rmq
    bitSemnificativ[1] = 0;
    for(int i = 2;i<=index;i++)
    {
        bitSemnificativ[i] = bitSemnificativ[i>>1] + 1;
    }
    for(int i = 1; i<=index;i++) rmq[0][i] = euler[i];
    for(int e = 1; (1<<e) <= index; e++)
    {
        for(int i = 1;i<=index;i++)
        {
            int j = i + (1<<(e-1));

            rmq[e][i] = rmq[e-1][i];
            if(j<=index && height[rmq[e-1][i]] > height[rmq[e-1][j]])
                rmq[e][i] = rmq[e-1][j];
        }
    }

    /*cout<<'\n';
    cout<<"RMQ :\n";
    for(int e = 0; (1<<e)<= 17;e++)
    {
        for(int i = 1;i<=index;i++) cout<<rmq[e][i]<<" ";
        cout<<'\n';
    }
    cout<<"\nEULER :\n";
    for(int i = 1; i<=index;i++) cout<<euler[i]<<" ";
    cout<<"\n\n";*/
    while(q--)
    {
        int x, y;
        cin>>x>>y;
        cout << lca(x, y) <<"\n";
    }
}