Cod sursa(job #3036718)

Utilizator raileanu-alin-gabrielRaileanu Alin-Gabriel raileanu-alin-gabriel Data 24 martie 2023 21:36:14
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.52 kb
#include <fstream>
#include <vector>
const int NMAX=500005;
const int LOG_MAX=25;

using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

int lca(int, int);
void dfs(int, int);
void construct_rmq();
int pt(int);
int query(int, int);

vector <int> v[NMAX];
int in[NMAX], lv[NMAX];
int rmq[NMAX][LOG_MAX];
int n, q, cnt;

int main()
{
    int i, a, b;
    fin>>n>>q;
    for(i=2; i<=n; i++)
    {
        fin>>a;
        v[i].push_back(a);
        v[a].push_back(i);
    }
    dfs(1, 0);
    construct_rmq();
    for(i=1; i<=q; i++)
    {
        fin>>a>>b;
        fout<<lca(a, b)<<'\n';
    }
    return 0;
}

void dfs(int nod, int lvl)
{
    lv[nod]=lvl;
    in[nod]=++cnt;
    rmq[in[nod]][0]=nod;
    for(auto i:v[nod])
    {
        if(!in[i])
        {
            dfs(i, lvl+1);
            rmq[++cnt][0]=nod;
        }
    }
}

void construct_rmq()
{
    int i, j;
    for(i=1; (1<<i)<=cnt; i++)
    {
        for(j=i; j<=cnt; j++)
        {
            if(lv[rmq[j][i-1]]<lv[rmq[j-(1<<(i-1))][i-1]])
                rmq[j][i]=rmq[j][i-1];
            else rmq[j][i]=rmq[j-(1<<(i-1))][i-1];
        }
    }
}

int lca(int a, int b)
{
    if(in[a]>in[b]) swap(a, b);
    return query(in[a], in[b]);
}

int query(int st, int dr)
{
    int pw=pt(dr-st+1);
    if(lv[rmq[st+(1<<pw)-1][pw]]<lv[rmq[dr][pw]])
        return rmq[st+(1<<pw)-1][pw];
    return rmq[dr][pw];
}

int pt(int nr)
{
    int p=0;
    while((1<<p)<=nr) p++;
    return p-1;
}