Cod sursa(job #2679503)

Utilizator HermioneMatei Hermina-Maria Hermione Data 30 noiembrie 2020 17:51:45
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.64 kb
#include <bits/stdc++.h>
using namespace std;

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

vector<vector<int>> children;
vector<int> t, first, v, h;
int N, M, n;

void rd()
{
    f>>N>>M;

    children.resize(N+1);
    t.resize(N+1, 1);
    first.resize(N+1, 0);
    h.resize(N+1, 0);

    for(int i=2; i<=N; i++)
    {
        f>>t[i];
        h[i] = h[t[i]] + 1;
        children[t[i]].push_back(i);
    }
}

void Euler(int x=1)
{
    v.push_back(x);
    first[x] = v.size() - 1;

    for(auto a:children[x])
        if(!first[a])
        {
            Euler(a);
            v.push_back(x);
        }
}

vector<vector<int>> spt; /// sparse table

int query(int i, int j)
{
    int k = log2(j - i + 1);

    if(h[v[spt[i][k]]] < h[v[spt[j + 1 - (1<<k)][k]]])
        return v[spt[i][k]];
    else
        return v[spt[j + 1 - (1<<k)][k]];
    ///return min(v[spt[i][k]], v[spt[j + 1 - (1<<k)][k]]);
}

void init()
{
    spt.resize(v.size(), vector<int>(log2(v.size()) + 1));

    for(int i=0; i < n; i++)
        spt[i][0] = i;

    for(int j=1; (1<<j) <= n; j++)
        for(int i=0; i + (1<<j) - 1 < n; i++)
            if(h[v[spt[i][j-1]]] < h[v[spt[i + (1<<(j-1))][j-1]]])
                spt[i][j] = spt[i][j-1];
            else
                spt[i][j] = spt[i + (1<<(j-1))][j-1];
}

void LCA()
{
    n=v.size();

    init();

    int x, y, i, j;
    while(f>>x>>y)
    {
        i = min(first[x], first[y]);
        j = max(first[x], first[y]);
        g<<query(i, j)<<'\n';
    }
}

int main()
{
    rd();
    Euler();
    LCA();
    f.close();
    g.close();
    return 0;
}