Cod sursa(job #2275602)

Utilizator alextodoranTodoran Alexandru Raul alextodoran Data 3 noiembrie 2018 12:42:10
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.71 kb
#include <bits/stdc++.h>

#define NM 100002
#define LM 20
#define LGM 1000002

using namespace std;

vector <int> gr[NM];

int n, m;
int e[LGM], le, pos[NM];
int l[NM];

void euler(int node, int level)
{
    l[node] = level;
    for(auto i : gr[node])
    {
        le++;
        e[le] = node;
        euler(i, level + 1);
    }
    le++;
    e[le] = node;
}

int mi[LM][LGM], mind[LM][LGM];

int main()
{
    ifstream fin ("lca.in");
    ofstream fout ("lca.out");
    fin >> n >> m;
    for(int i = 2; i <= n; i++)
    {
        int t;
        fin >> t;
        gr[t].push_back(i);
    }
    euler(1, 1);
    for(int i = 1; i <= le; i++)
        if(pos[e[i]] == 0)
            pos[e[i]] = i;
    for(int i = 1; i <= le; i++)
    {
        mi[0][i] = l[e[i]];
        mind[0][i] = e[i];
    }
    for(int i = 1; (1 << i) <= le; i++)
        for(int j = 1; j <= le - (1 << i) + 1; j++)
        {
            if(mi[i - 1][j] < mi[i - 1][j + (1 << (i - 1))])
            {
                mi[i][j] = mi[i - 1][j];
                mind[i][j] = mind[i - 1][j];
            }
            else
            {
                mi[i][j] = mi[i - 1][j + (1 << (i - 1))];
                mind[i][j] = mind[i - 1][j + (1 << (i - 1))];
            }
        }
    for(int i = 1; i <= m; i++)
    {
        int a, b;
        fin >> a >> b;
        a = pos[a];
        b = pos[b];
        if(a > b)
            swap(a, b);
        int lg = b - a + 1;
        int k;
        for(k = 0; (1 << (k + 1)) <= lg; k++);
        if(mi[k][a] < mi[k][b - (1 << k) + 1])
            fout << mind[k][a] << "\n";
        else
            fout << mind[k][b - (1 << k) + 1] << "\n";
    }
    return 0;
}