Cod sursa(job #2128788)

Utilizator DawlauAndrei Blahovici Dawlau Data 12 februarie 2018 05:29:29
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.64 kb
#include<fstream>
#include<list>
#include<cmath>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX = 100005, LOG2NMAX = 18;

list<int> graph[NMAX];

int rmq[LOG2NMAX][2 * NMAX], firstPos[NMAX], depth[NMAX];
int nodesCount, T, eulerLength;


inline void read_data(){

    fin >> nodesCount >> T;

    int node, father;
    for(node = 2; node <= nodesCount; ++node){

        fin >> father;
        graph[father].push_back(node);
    }
}

void DFS(int node, int level){

    rmq[0][++eulerLength] = node;
    firstPos[node] = eulerLength;
    depth[node] = level;

    for(const auto &nextNode: graph[node]){

       DFS(nextNode, level + 1);
       rmq[0][++eulerLength] = node;
    }
}

inline int minDepth(int a,int b){

    if(depth[a] < depth[b])
        return a;
    return b;
}

inline void createRMQ(){

    int row, column;
    for(row = 1; (1 << row) <= eulerLength; ++row)
        for(column = 1; column <= eulerLength - (1 << row) + 1; ++column)
            rmq[row][column] = minDepth(rmq[row - 1][column], rmq[row - 1][column + (1 << (row - 1))]);
}

inline void solveQueries(){

    int sequenceLength, levelInRMQ, x, y;

    while(T--){

        fin >> x >> y;
        if(firstPos[x] > firstPos[y])
            swap(x, y);
        sequenceLength = firstPos[y] - firstPos[x] + 1;
        levelInRMQ = (int)(log2(sequenceLength));
        fout << minDepth(rmq[levelInRMQ][firstPos[x]], rmq[levelInRMQ][firstPos[x] + sequenceLength - (1 << levelInRMQ)]) << '\n';
    }
}

int main(){

    read_data();
    DFS(1, 1);
    createRMQ();
    solveQueries();
}