Cod sursa(job #1840225)

Utilizator vladm98Munteanu Vlad vladm98 Data 3 ianuarie 2017 23:00:37
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.62 kb
#include <bits/stdc++.h>
#define FIT(x, v) for (vector<int>::iterator x = v.begin(); x!=v.end(); ++x)
using namespace std;
const int MAX = 100001;
vector <int> graf[MAX];
vector <int> noduri_lant[MAX];
int sz, maxim;
int tata[MAX];
int numar_lanturi;
int poz[MAX];
int lg[MAX];
int dp[20][MAX];
int subarb[MAX];
int lant[MAX];
int nivel_lant[MAX];
void dfs (int nod)
{
    subarb[nod] = 1;
    int where = 0;
    FIT (x, graf[nod])
    {
        dfs (*x);
        subarb[nod] += subarb[*x];
        if (subarb[where] < subarb[*x])
            where = *x;
    }
    if (graf[nod].size() == 0)
    {
        ++numar_lanturi;
        lant[nod] = numar_lanturi;
        noduri_lant[numar_lanturi].push_back(nod);
        poz[nod] = 0;
        return ;
    }
    lant[nod] = lant[where];
    noduri_lant[lant[nod]].push_back(nod);
    poz[nod] = noduri_lant[lant[nod]].size()-1;
}
void dfs2 (int nod)
{
    if (poz[nod] == noduri_lant[lant[nod]].size() - 1)
    {
        ++sz;
        nivel_lant[lant[nod]] = sz;
        maxim = max(maxim, sz);
    }
    dp[0][nod] = tata[noduri_lant[lant[nod]].back()];
    FIT(x, graf[nod])
        dfs2(*x);
    if (poz[nod] == noduri_lant[lant[nod]].size() - 1)
        --sz;
}
int LCA (int x, int y)
{
    int lantx = lant[x], lanty = lant[y];
    if (nivel_lant[lantx] < nivel_lant[lanty])
        swap(x, y);
    lantx = lant[x];
    lanty = lant[y];
    int diferenta = nivel_lant[lantx] - nivel_lant[lanty];
    for (int put = lg[diferenta]+1; put >= 0; --put)
        if (1<<put <= diferenta)
            diferenta -= (1<<put), x = dp[put][x];
    lantx = lant[x];
    if (lantx == lanty)
    {
        if (poz[x]>poz[y])
            return x;
        return y;
    }
    for (int put = lg[nivel_lant[lantx]]+1; put>=0; --put)
    {
        if ((nivel_lant[lantx] > (1<<put)) && (lant[dp[put][x]] != lant[dp[put][y]]))
        {
            x = dp[put][x];
            y = dp[put][y];
            lantx = lant[x];
        }
    }
    x = dp[0][x];
    y = dp[0][y];
    if (poz[x]>poz[y])
        return x;
    return y;
}
int main()
{
    ifstream fin ("lca.in");
    ofstream fout ("lca.out");
    int n, m, x, y;
    fin >> n >> m;
    for (int i = 2; i<=n; ++i)
    {
        fin >> tata[i];
        graf[tata[i]].push_back(i);
        lg[i] = lg[i>>1] + 1;
    }
    dfs(1);
    dfs2(1);
    for (int i = 1; i <= lg[maxim]+1; ++i)
        for (int j = 1; j<=n; ++j)
            dp[i][j] = dp[i-1][dp[i-1][j]];
    for (int i = 0; i<m; ++i)
    {
        fin >> x >> y;
        fout << LCA (x, y) << '\n';
    }
    return 0;
}