Cod sursa(job #3353352)

Utilizator Mirc100Mircea Octavian Mirc100 Data 6 mai 2026 13:55:15
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.68 kb
#include <iostream>
#include <vector>
#include <fstream>
#include <cmath>

using namespace std;

const int nrMaxNoduri = 1e5;
int euler[nrMaxNoduri << 1], nivel[nrMaxNoduri << 1], pozitii[nrMaxNoduri << 1];

vector<int> lf[nrMaxNoduri+1];
int rmq[nrMaxNoduri << 1][20];

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

int poz;

void calculeazaRMQ(int n){
    int l=log2(n);
    for(int i=0; i<n; i++){
        rmq[i][0] = i;
    }
    for(int j=1; j<=l; j++){
        for(int i=0; i<n; i++){
            if(i+(1<<(j))<=n)
                //rmq[i][j]=min(rmq[i][j-1], rmq[i+(1<<(j-1))][j-1]);
                if (nivel[rmq[i][j-1]] < nivel[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];
        }
    }
}

int interogare(int a, int b)
{
    if (a > b) swap(a,b);
    int lung=b-a+1, k=(int)(log2(lung));
    //return min(rmq[a][k], rmq[b-(1<<k)+1][k]);
    if (nivel[rmq[a][k]] < nivel[rmq[b-(1<<k)+1][k]])
        return rmq[a][k];
    return rmq[b-(1<<k)+1][k];
}
void parcurgere(int x, int niv) {
    euler[poz] = x;
    nivel[poz] = niv;
    pozitii[x] = poz;
    poz++;
    for (auto y : lf[x]) {
        parcurgere(y,niv+1);
        euler[poz] = x;
        nivel[poz] = niv;
        poz++;
    }
}

int main()
{
    int n, m , t;
    fin >> n >> m;
    for (int i = 2; i <= n; i++) {
        fin >> t;
        lf[t].push_back(i);
    }
    parcurgere(1,0);

    calculeazaRMQ(poz);
    int x, y;
    for (int i = 0; i < m; i++) {
        fin >> x >> y;
        fout << euler[interogare(pozitii[x],pozitii[y])] << " ";
    }
    return 0;
}