Cod sursa(job #1956086)

Utilizator Train1Train1 Train1 Data 6 aprilie 2017 14:45:29
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.99 kb
#include <iostream>
#include <fstream>
#include <vector>
#define NMax 100001
#define MAXNR 999999999
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector <int> v [NMax];
vector <pair <int, int> > rEuler;
int x, y, n, m, pos, nr = 1;
int First[NMax];
pair <int, int> val;
void DF(int R, int nivel) {
    rEuler.push_back(make_pair(R, nivel));
    First[R] = nr;
    nr++;
    for(int i = 0; i < v[R].size(); i++) {
        DF(v[R][i], nivel + 1);
        rEuler.push_back(make_pair(R, nivel));
        nr++;
    }
}
int RMQ[33][NMax << 4];
int RMQi[33][NMax << 4];
int LG[NMax<<4];
int main()
{
    fin>>n>>m;
    for(int i = 2; i <= n; i++) {
        fin>>x;
        v[x].push_back(i);
    }
    rEuler.push_back(make_pair(0, 0));
    DF(1, 0);
    nr--;
    int logP = -1;
    for(int i = 1; i <= nr; i++) {
        RMQ[0][i] = rEuler[i].second;
        RMQi[0][i] = rEuler[i].first;
        if((i & (i - 1)) == 0) {
            logP++;
        }
        LG[i] = logP;
    }

    int p = 1, k;
    for(int i = 1; i <= LG[nr] + 1; i++) {
        k = p;
        p = p<<1;
        for(int j = 1; j <= nr - p + 1; j++) {
            if(RMQ[i - 1][j] > RMQ[i - 1][j + k]) {
                RMQ[i][j] = RMQ[i - 1][j + k];
                RMQi[i][j] = RMQi[i - 1][j + k];
            } else {
                RMQ[i][j] = RMQ[i - 1][j];
                RMQi[i][j] = RMQi[i - 1][j];
            }
        }
    }

    int Left, Right;
    for(int i = 1; i <= m; i++) {
        fin>>x>>y;
        Left = First[x];
        Right = First[y];
        if(First[x] > First[y]) {
            Left = First[y];
            Right = First[x];
        }

        int dif = LG[Right - Left + 1];
        int p = 1<<dif;
        if(RMQ[dif][Left] > RMQ[dif][Right - p + 1]) {
            fout<<RMQi[dif][Right - p];
        } else {
            fout<<RMQi[dif][Left];
        }
        fout<<'\n';
    }
    fin.close();
    fout.close();
    return 0;
}