Cod sursa(job #2403920)

Utilizator alexoloieriAlexandru Oloieri alexoloieri Data 12 aprilie 2019 02:25:10
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.79 kb
#include <cstdio>
#include <vector>
#define nmax 200005
#define pb push_back
using namespace std;
FILE *fin=fopen("lca.in","r");
FILE *fout=fopen("lca.out","w");
vector<int>G[nmax];
int n, m, x;
int act, euler[2*nmax], h[2*nmax], first[nmax], ha;
int rmq[2*nmax][30], n1, n2, l, r;
void dfs(int k)
{
    if (!first[k]) first[k] = act+1;
    if (!G[k].size())
    {
        ++act;
        euler[act] = k;
        h[act] = ha+1;
        return;
    }
    for (int i=0; i<G[k].size(); ++i)
    {
        ++act;
        ++ha;
        euler[act] = k;
        h[act] = ha;
        dfs(G[k][i]);
        ++act;
        euler[act] = k;
        h[act] = ha;
        --ha;
    }
}
int l2(int x)
{
    if (x<=1) return 0;
    int ans = 0, act = 1;
    while(true)
    {
        if (act > x)
            return ans - 1;
        ++ans, act*=2;
    }
}
int main()
{
    fscanf(fin,"%d %d",&n,&m);
    for (int i=2; i<=n; ++i)
    {
        fscanf(fin,"%d",&x);
        G[x].pb(i);
    }
    dfs(1);
    for (int i=1; i<=act; ++i)
        rmq[i][0] = i;
    for (int j=1; (1<<j)<=act; ++j)
        for (int i=1; i+(1<<j)-1<=act; ++i)
            if (h[rmq[i][j-1]] < h[rmq[i+(1<<(j-1))][j-1]])
                rmq[i][j] = rmq[i][j-1];
            else
                rmq[i][j] = rmq[i+(1<<(j-1))][j-1];
    for (int i=1; i<=m; ++i)
    {
        fscanf(fin,"%d %d",&n1, &n2);
        l = first[n1];
        r = first[n2];
        if (r < l) swap(l, r);
        int dist = r - l + 1;
        int wh = l2(dist);
        int add = dist - (1<<wh);
        if (h[rmq[l][wh]] < h[rmq[l+add][wh]])
            fprintf(fout,"%d\n", euler[rmq[l][wh]]);
        else
            fprintf(fout,"%d\n", euler[rmq[l+add][wh]]);
    }
    fclose(fin);
    fclose(fout);
    return 0;
}