Cod sursa(job #2772690)

Utilizator RamanujanNeacsu Mihnea Ramanujan Data 2 septembrie 2021 12:06:18
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.12 kb
#include <fstream>
#include <vector>
#include <queue>

const int maxn=1e5+2;
const int inalt=19;
using namespace std;

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

int dads[maxn], depth[maxn], stramosi[inalt][maxn];
vector<int> sons[maxn];

void bfs(int i){
    queue<int> q;
    q.push(i);
    while(!q.empty()){
        int val=q.front();
        for(int j=0; j<sons[val].size(); j++){
            depth[sons[val][j]]=depth[val]+1;
            q.push(sons[val][j]);
        }
        q.pop();
    }
}
void equalizeDepth(int &x, int&y){//x e mai mare ca y
    int diff=depth[x]-depth[y], currBit=0;
    while(diff>0){
       if(diff&1){
          x=stramosi[currBit][x];
       }
       currBit++;
       diff>>=1;
    }
}
int getLowestAncestor(int x, int y){
    if(depth[x]>depth[y]){//daca x e mai adanc
         equalizeDepth(x, y);
    }
    else
       equalizeDepth(y, x);
    //pasul 2: cautam binar LCA-ul
    int sol;
    if(x!=y){
       for(int currBit=inalt-1; currBit>=0; currBit--){
          if(stramosi[currBit][x]==stramosi[currBit][y]){//daca am un stramos comun de ordinul ala
            sol=stramosi[currBit][x];//ala poate sa fie, daca e mai mic, tetez ulterior
          }
          else{//altfel, urc cu acel ordin, LCA-ul va fi mai sus
            x=stramosi[currBit][x];
            y=stramosi[currBit][y];
          }
       }
       return sol;
    }
    else{
       return x;//pot sa fie egale, caz in care urcam excesiv, asa ca iesim pe loc
    }
}
int main()  {
    int n, m; cin>>n>>m;
    for(int i=0; i<n-1; i++){
        cin>>dads[i+2];//citim direct tatii
        sons[dads[i+2]].push_back(i+2);
    }
    //fac stramosii pt RMQ

    for(int j=0, lung=1; lung<n; j++, lung<<=1){
        for(int i=1; i<=n; i++){
            if(j==0){
                stramosi[j][i]=dads[i];
            }
            else{
                stramosi[j][i]=stramosi[j-1][stramosi[j-1][i]];
            }
        }
    }
    bfs(1);
    for(int i=0; i<m; i++){
        int x, y; cin>>x>>y;
        cout<<getLowestAncestor(x, y)<<"\n";
    }
    return 0;
}