Cod sursa(job #2115940)

Utilizator trifangrobertRobert Trifan trifangrobert Data 27 ianuarie 2018 11:28:21
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.59 kb
#include <fstream>
#include <vector>

using namespace std;

int rmq[22][400010];
int E[2000010], k;
int niv[2000010], poz[100010];
int a[1000010], n, m;
int lg[100010];
vector <int> L[1000010];

void Euler(int nod, int nivel)
{
    E[++k] = nod;
    niv[k] = nivel;
    poz[nod] = k;
    for (auto i : L[nod])
    {
        Euler(i, nivel + 1);
        E[++k] = nod;
        niv[k] = nivel;
    }
}

int main()
{
    ifstream fin("lca.in");
    ofstream fout("lca.out");
    fin >> n >> m;
    int x, y;
    for (int i = 2;i <= n;++i)
    {
        fin >> x;
        L[x].push_back(i);
    }
    Euler(1, 1);
    for (int i = 1;i <= k;++i)
        rmq[0][i] = i;
    ///fasim lg
    lg[1] = 0;
    for (int i = 2;i <= k;++i)
        lg[i] = lg[i >> 1] + 1;
    //int N = lg[k];
    ///rmq;
    for (int p = 1;(1 << p) <= k;++p)
        for (int j = 1;j + (1 << p) - 1 <= k;++j)
        {
            x = niv[rmq[p - 1][j]];
            y = niv[rmq[p - 1][j + (1  << (p - 1))]];
            if (x < y)
                rmq[p][j] = rmq[p - 1][j];
            else
                rmq[p][j] = rmq[p - 1][j + (1  << (p - 1))];
        }
    ///query
    int p;
    for (int i = 1;i <= m;++i)
    {
        fin >> x >> y;
        x = poz[x];
        y = poz[y];
        if (x > y)
            swap(x, y);
        p = lg[y - x + 1];
        x = rmq[p][x];
        y = rmq[p][y - (1 << p) + 1];
        if (niv[x] < niv[y])
            fout << E[x] << "\n";
        else
            fout << E[y] << "\n";
    }
    fin.close();
    fout.close();
    return 0;
}