Cod sursa(job #2331565)

Utilizator FrequeAlex Iordachescu Freque Data 29 ianuarie 2019 18:21:55
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.06 kb
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define enter cout << '\n'

using namespace std;

typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef vector <int> vi;
typedef vector <pii> vii;
typedef vector <ll> vl;
typedef vector <pll> vll;
typedef queue <int> qi;
typedef queue <pii> qii;
typedef queue <ll> ql;
typedef queue <pll> qll;

const int INF = 0x3f3f3f3f;
const int MOD = 100003;
const double EPSILON = 0.0000000001;
const int NMAX = 1e5 + 5;
const int LMAX = 2e5 + 5;
const int EMAX = log2(NMAX) + 5;

ifstream fin("lca.in");
ofstream fout("lca.out");

vi graph[NMAX];
vii line;
pii rmq[EMAX][LMAX];
int n, m;
int ap[NMAX], lg[LMAX];
bool vis[NMAX];

void dfs(int node, int depth)
{
    vis[node] = true;
    line.pb(mp(depth, node));
    ap[node] = line.size() - 1;
    for (int next: graph[node])
        if (!vis[next])
        {
            dfs(next, depth + 1);
            line.pb(mp(depth, node));
        }
}

void build()
{
    lg[1] = 0;
    for (int i = 2; i <= line.size(); ++i)
        lg[i] = lg[i / 2] + 1;

    for (int i = 0; i < line.size(); ++i)
        rmq[0][i] = line[i];

    for (int i = 1; (1 << i) < line.size(); ++i)
        for (int j = 0; j + (1 << i) - 1 < line.size(); ++j)
            rmq[i][j] = min(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);
}

pii query(int st, int dr)
{
    int len = dr - st + 1;
    return min(rmq[lg[len]][st], rmq[lg[len]][dr - (1 << lg[len]) + 1]);
}

void read()
{
    int x;

    fin >> n >> m;
    for (int i = 2; i <= n; ++i)
    {
        fin >> x;
        graph[i].pb(x);
        graph[x].pb(i);
    }
}

int main()
{
    read();
    dfs(1, 0);
    build();

    while (m--)
    {
        int st, dr;
        fin >> st >> dr;
        st = ap[st];
        dr = ap[dr];
        if (st > dr) swap(st, dr);
        fout << query(st, dr).se << '\n';
    }

    return 0;
}