Cod sursa(job #2272662)

Utilizator AlexandruabcdeDobleaga Alexandru Alexandruabcde Data 30 octombrie 2018 15:51:44
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.03 kb
#include <bits/stdc++.h>

using namespace std;

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

vector <int> lin;
vector <int> node;
vector <int> G[100005];

int rmq[(int)log2(200005) + 1][200005];

int n, m, x, y, l;

int poz[100005];

bool viz[100005];

void dfs (int nod, int l)
{
    lin.push_back(l);
    node.push_back(nod);
    for (int i = 0; i < G[nod].size(); i++)
    {
        if (!viz[G[nod][i]])
        {
            dfs(G[nod][i], l+1);
            lin.push_back(l);
            node.push_back(nod);
        }
    }

    viz[nod] = true;
}
int main()
{
    f >> n >> m;

    for (int i = 1; i <= n - 1; i++)
    {
        f >> x;
        G[x].push_back(i+1);
    }

    dfs(1, 1);

    for (int i = 0; i < lin.size(); i++)
    {
        rmq[0][i] = i;
    }

    for (int i = 1; i <= (int)log2(lin.size()); i++)
    {
        for (int j = 0; j < lin.size() - (1 << i) + 1; j++)
        {
            if (lin[rmq[i-1][j]] < lin[rmq[i-1][j + (1<<(i-1))]])
            {
                rmq[i][j] = rmq[i-1][j];
            }
            else rmq[i][j] = rmq[i-1][j + (1 << (i-1))];
        }
    }

    /*for (int i = 0; i < node.size(); i++)
        g << node[i] << " ";
    g << '\n';
    for (int i = 0; i < lin.size(); i++)
        g << lin[i] << " ";*/

    for (int i = 0; i < node.size(); i++)
    {
        if (poz[node[i]] == 0 && node[i] != 1)
        {
            poz[node[i]] = i;
        }
    }

    /*g << '\n';
    for (int i = 1; i <= n; i++)
        g << poz[i] << " ";*/

    for (int i = 1; i <= m; i++)
    {
        f >> x >> y;
        if (poz[y] == poz[x]) g << x << '\n';
        else {

            if (poz[y] < poz[x]) swap(x, y);

            l = (int)log2(poz[y] - poz[x]);

            if (lin[rmq[l][poz[x]]] > lin[rmq[l][poz[y] - (1 << l) + 1]])
            {
                g << node[rmq[l][poz[y] - (1 << l) + 1]] << '\n';
            }
            else g << node[rmq[l][poz[x]]] << '\n';

        }
    }
    return 0;
}