Cod sursa(job #3245306)

Utilizator Ruxandra009Ruxandra Vasilescu Ruxandra009 Data 28 septembrie 2024 13:03:35
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
#include <algorithm>
#include <fstream>
#include <vector>

using namespace std;

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

const int nmax = 1005;

struct ceva{
    int poz, lv;
}ord[nmax];

int dad[nmax], n, q, niv[nmax], t[nmax][30];
vector<int> v[nmax];

bool cmp(ceva x, ceva y){
    return x.lv < y.lv;
}

void dfs(int nod)
{
    for(auto x : v[nod]){
        niv[x] = niv[nod] + 1;
        dfs(x);
    }
}

int lca(int x, int y)
{
    if(niv[x] != niv[y])
    {
        if(niv[x] < niv[y]){
            int dif = niv[y] - niv[x];
            for(int i = 0; i <= 20; i ++)
                if((1<<i)&dif)
                    y = t[y][i];
        }

        else{
            int dif = niv[x] - niv[y];
            for(int i = 0; i <= 20; i ++)
                if((1<<i)&dif)
                    x = t[x][i];
        }
    }

    if(y == x)
        return x;

    for(int i = 20; i >= 0; i --)
        if(t[x][i] != t[y][i])
            x = t[x][i], y = t[y][i];

    return t[x][0];
}

int main()
{
    f >> n >> q;
    for(int i = 2; i <= n; i ++)
    {
        f >> dad[i];
        v[dad[i]].push_back(i);
    }

    niv[1] = 1; dfs(1);

    for(int i = 1; i <= n; i ++)
        ord[i] = {i, niv[i]};

    sort(ord + 1, ord + n + 1, cmp);

    for(int i = 1; i <= n; i ++)
    {
        int k = ord[i].poz;
        t[k][0] = dad[k];

        for(int x = 1; x <= 20; x ++)
            t[k][x] = t[t[k][x - 1]][x - 1];
    }

    for(int i = 1; i <= q; i ++)
    {
        int x, y; f >> x >> y;
        g << lca(x, y) << '\n';
    }
    return 0;
}