Cod sursa(job #3294810)

Utilizator Mirc100Mircea Octavian Mirc100 Data 28 aprilie 2025 23:32:04
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.99 kb
#include<fstream>

using namespace std;

struct node{
    int valoare;
    node* next;
};
void adaugareInceput(node* &head,  int x)
{
    node* element=new node;
    element->valoare=x;
    ///element->next=NULL;
    element->next=head; 

    head=element;

}
const int NMAX=100005;
const int LMAX=18;

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

int n, Q, a, b;
int nivel[NMAX << 1], euler[NMAX << 1],LOG[NMAX << 1], prima_apar[NMAX]; //eluer tur- 2*nr muchii
int rmq[NMAX << 2][LMAX];
node* G[NMAX];
node* lastG[NMAX];
void tur_euler(int nod, int niv, int &k) { 
    k=k+1;
    euler[k] = nod;
    nivel[k] = niv ;
    prima_apar[nod] = k;
    node *p=G[nod];
    while(p){
        tur_euler(p->valoare,niv+1,k);
        k=k+1; 
        euler[k] = nod;
        nivel[k] = niv ;
        p=p->next;
    }

}
void preprocesare_euler(int n){
    
    LOG[1]=0;
    for (int i = 2; i<=n; i++) {
        LOG[i] = LOG[i/2]+1;
    }


    for (int i = 0; i<n; i++) {
        rmq[i][0] = i;
    }
    for(int j=1;(1<<j)<=n;j++)  
        for(int i=0;i+(1<<j)-1<n;i++) 
            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 query(int a,int b){
    int x = prima_apar[a], y = prima_apar[b];

    if (x > y) swap(x, y); 
 
    int k = LOG[y - x + 1];
    if (nivel[rmq[x][k]]<nivel[rmq[y - (1 << k) + 1][k]])
        return euler[rmq[x][k]]; 
    else
        return euler[rmq[y - (1 << k) + 1][k]];
}


int main() {

    fin >> n >> Q;
    for (int i = 1; i<=n; i++) 
        G[i]=   NULL;
    for (int i = 2; i<=n; i++) { 
        fin >> a;
        adaugareInceput(G[a],i); 
    }
    int k=-1;
    tur_euler(1, 0, k);
    
    preprocesare_euler(k+1); 

    
    
    for(int i=0;i<Q;i++){
        fin >> a >> b;
        fout << query(a, b) << "\n";
    }
    fout.close();
    return 0;
}