Cod sursa(job #2369426)

Utilizator circeanubogdanCirceanu Bogdan circeanubogdan Data 5 martie 2019 23:10:33
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.8 kb
#include <fstream>
#include <algorithm>
#include <vector>
#define DIM 100002

using namespace std;

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

int n, Q, cnt;
int father[DIM], put[DIM], first[DIM], last[DIM];

vector<int> arb[DIM];

struct node{
    int node, lvl;
};

node euler[3 * DIM];
node rmq[18][DIM];

void dfs(int nod, int level){
    euler[++cnt].node = nod;
    euler[cnt].lvl = level;
    first[nod] = cnt;
    for(auto it : arb[nod]){
        dfs(it, level + 1);
        euler[++cnt].node = nod;
        euler[cnt].lvl = level;
    }
    last[nod] = cnt;
}

int main()
{
    in>>n>>Q;
    for(int i = 2; i <= n; ++ i){
        in>>father[i];
        arb[father[i]].push_back(i);
    }

    dfs(1, 1);

    for(int i = 1; i <= cnt; ++ i){
        rmq[0][i] = euler[i];
    }

    for(int put = 1; (1<<put) <= cnt; ++ put){
        int i;
        for(i = 1; i + (1<<(put - 1)) <= cnt; ++ i){
            if(rmq[put - 1][i].lvl <= rmq[put - 1][i + (1<<(put - 1))].lvl){
                rmq[put][i] = rmq[put - 1][i];
            }
            else{
                rmq[put][i] = rmq[put - 1][i + (1<<(put - 1))];
            }
        }
        for(; i <= cnt; ++ i)
            rmq[put][i] = rmq[put - 1][i];
    }

    put[1] = 0;

    for(int i = 2; i <= cnt; ++ i){
        put[i] = 1 + put[i / 2];
    }

    while(Q--){
        int x, y;
        in>>x>>y;
        int left = min(first[x], first[y]);
        int right = max(last[x], last[y]);
        int putere = put[right - left + 1];
        if(rmq[putere][left].lvl < rmq[putere][right - (1<<putere) + 1].lvl){
            out<<rmq[putere][left].node<<'\n';
        }
        else{
            out<<rmq[putere][right - (1<<putere) + 1].node<<'\n';
        }
    }



    return 0;
}