Cod sursa(job #2351838)

Utilizator sandupetrascoPetrasco Sandu sandupetrasco Data 22 februarie 2019 18:59:31
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.96 kb
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define MOD 1000000007
using namespace std;
typedef long long ll;
typedef pair< int , int > PII;

ll n, a[100100], x, y, m, k;
string s;

class RMQ {
 private:
    vector < int > logVec;
    vector < vector < int > > rmqVec;

 public:
    RMQ(vector < int > _RMQ){
        logVec.assign(_RMQ.size() + 1, 0);
        for (int i = 2; i < logVec.size(); i++) {
            logVec[i] = logVec[i / 2] + 1;
        }

        rmqVec.assign(logVec.back() + 1, vector < int >(_RMQ.size()));
        rmqVec[0] = _RMQ;

        for (int logX = 1; logX < rmqVec.size(); logX++) {
            for (int i = 0; i + (1 << logX) <= _RMQ.size(); i++) {
                rmqVec[logX][i] = min(rmqVec[logX - 1][i], rmqVec[logX - 1][i + (1 << (logX - 1))]);
            }
        }
    }

    int getMin(int l, int r) { // ! returns the answer for the interval [l, r) !
        int logX = logVec[r - l];
        return min(rmqVec[logX][l], rmqVec[logX][r - (1 << logX)]);
    }
};

vector < int > bck;
vector < int > fst;
vector < int > euler;
vector < int > V[100100];

void eulerTour(int curr, int dad) {
    int newIndex = bck.size();
    bck.push_back(curr);
    fst[curr] = euler.size();
    euler.push_back(newIndex);

    for (auto it : V[curr]) {
        if (it == dad) continue;

        eulerTour(it, curr);
        euler.push_back(newIndex);
    }
}

int main(){
    ifstream cin("lca.in");
    ofstream cout("lca.out");
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    
    cin >> n >> m;
    for (int i = 1, x; i < n; i++) {
        cin >> x;
        V[x].push_back(i + 1);
    }

    fst.assign(n + 1, -1);
    eulerTour(1, 1);

    RMQ rmq(euler);

    while (m--) {
        int x, y;
        cin >> x >> y;

        int nodeX = fst[x], nodeY = fst[y];
        if (nodeX > nodeY) swap(nodeX, nodeY);

        int newIndex = rmq.getMin(nodeX, nodeY + 1);
        int oldIndex = bck[newIndex];

        cout << oldIndex << "\n";
    }
	return 0;
}