Cod sursa(job #3224398)

Utilizator Mirc100Mircea Octavian Mirc100 Data 15 aprilie 2024 11:51:24
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.9 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; //devine NULL daca head este NULL

    head=element;

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

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

int k, 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 parcurg(int nod, int niv) {
    k=k+1;
    euler[k] = nod;
    nivel[k] = niv ;
    prima_apar[nod] = k;

    for (node* p= G[nod]; p!=NULL; p=p->next) {
        parcurg(p->valoare, niv +1);
  
        k=k+1;
        euler[k] = nod;
        nivel[k] = niv ;
    }

}
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);
    }
    k=-1;
    parcurg(1, 0);


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


    for (int i = 0; i<n; i++) {
        rmq[i][0] = i;//indice
    }

    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];



    while (Q--) {
        fin >> a >> b;
        fout << query(a, b) << "\n";
    }

    return 0;
}