Cod sursa(job #2283251)

Utilizator Dragne.Andrei11Dragne Andrei Dragne.Andrei11 Data 15 noiembrie 2018 11:42:20
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.63 kb
#include <bits/stdc++.h>

using namespace std;

const int nmax=100005;
const int pmax=20;

vector <int> g[nmax];
bool visited[nmax];
int depth[nmax];
int first[nmax];
int euler[nmax*4];
int d[pmax][nmax*4];
int loga[nmax*4];
int cnt;

void dfs(int start_node)
{
    visited[start_node]=true;
    if(first[start_node]==0)
        first[start_node]=cnt;
    euler[cnt++]=start_node;
    for(int i=0;i<g[start_node].size();i++)
    {
        if(visited[g[start_node][i]]==false)
        {
            dfs(g[start_node][i]);
            euler[cnt++]=start_node;
        }
    }
}
void rmq()
{
    for(int i=1;i<=cnt;i++)
        d[0][i]=euler[i];
    for(int p=1;(1<<p)<cnt;p++)
    {
        for(int i=1;i+(1<<p)-1<=cnt;i++)
        {
            if(depth[d[p-1][i]]<depth[d[p-1][i+(1<<p-1)]])
                d[p][i]=d[p-1][i];
            else
                d[p][i]=d[p-1][i+(1<<p-1)];
        }
    }
    loga[1]=0;
    for(int i=2;i<=cnt;i++)
        loga[i]=loga[i/2]+1;
}
void lca(int x, int y)
{
    x=first[x];
    y=first[y];
    if(x>y)
        swap(x, y);
    int rasp=min(d[loga[y-x]][x], d[loga[y-x]][y-(1<<loga[y-x])+1]);
    printf("%d\n", rasp);
}

int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    int n, m;

    scanf("%d%d", &n, &m);
    for(int i=1;i<=n-1;i++)
    {
        int x;
        scanf("%d", &x);
        g[x].push_back(i+1);
        depth[i+1]=depth[x]+1;
    }
    cnt=1;
    dfs(1);
    rmq();
    for(int i=1;i<=m;i++)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        lca(x, y);
    }

    return 0;
}