Cod sursa(job #2713746)

Utilizator DanielznaceniDaniel Danielznaceni Data 28 februarie 2021 15:40:50
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.71 kb
#include <bits/stdc++.h>
#define lim 100005
using namespace std;

ifstream in("lca.in");
ofstream out("lca.out");

int n, m, path[2*lim], pos[lim], k=0, mat[22][lim*2];
int ran[2*lim];
vector <int> v[lim];

void read()
{
    int x;
    in>>n>>m;
    for(int i=2; i<=n; ++i)
    {
        in>>x;
        v[x].push_back(i);
    }
}

void dfs(int x,int r)
{
    path[++k]=x;
    ran[k]=r;
    pos[x]=k;
    for(int i=0; i<v[x].size(); ++i)
    {
        dfs(v[x][i], r+1);
        path[++k]=x;
        ran[k]=r;
        pos[x]=k;
    }

}

int find_pow(int x)
{
    int pw=1;
    for(int i=0; i<=22; ++i)
    {
        if(pw>x)
        {
            return i-1;
        }
        mat[i][0]=pw;
        pw=pw*2;
    }
}

void create_sparse_table()
{
    int l=2*n-1;
    int pw=find_pow(l);
    for(int i=0; i<=pw; ++i)
    {
        for(int j=1; j+mat[i][0]-1<=l; ++j)
        {
            if(i==0)
            {
                mat[i][j]=path[j];
            }
            else if(i>0)
            {
                mat[i][j]=min(mat[i-1][j],mat[i-1][j+mat[i-1][0]]);
            }
            //cout<<mat[i][j]<<" ";
        }
        //cout<<'\n';
    }
}

void solve()
{
    int x, y;
    for(int i=1; i<=m; ++i)
    {
        in>>x>>y;
        if(pos[x]>pos[y])
        {
            swap(x,y);
        }
        int lin=find_pow(pos[y]-pos[x]+1);
        out<<min(mat[lin][pos[x]], mat[lin][pos[y]-mat[lin][0]+1])<<'\n';
    }
}

int main()
{
    read();
    dfs(1, 1);
    /*for(int i=1; i<=2*n; ++i)
    {
        cout<<path[i]<<" "<<ran[i]<<" "<<pos[i]<<'\n';
    }
    cout<<'\n';*/
    create_sparse_table();
    solve();
    return 0;
}