Cod sursa(job #2180525)

Utilizator remus88Neatu Remus Mihai remus88 Data 20 martie 2018 22:12:28
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
#include <fstream>
#include <vector>
#include <cmath>
#include <bitset>
#define Nmax 100009
#define Logmax 18

using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");

int n,m,s[Logmax][Nmax],x,y,d[Nmax];
vector <int> G[Nmax];

void build_ancestor(int kmax) {

    s[0][1]=0;

    for (int i=2; i<=n; ++i) {

        f>>x;
        s[0][i]=x;
        G[x].push_back(i);
    }
    for (int k=1; k<=kmax; ++k)
        for (int i=1; i<=n; ++i) {

            s[k][i] = s[ k-1 ][ s[k-1][i] ];
        }
}

int get_ancestor(int x, int p) {

    int kmax=log2(p);

    for (int k=0; k<=kmax; ++k) {

        if (p & 1) {

            x = s[k][x];
        }

        p >>= 1;
    }

    return x;
}

int LCA(int x, int y) {

    if (d[x]>d[y]) {

            x = get_ancestor(x, d[x]-d[y]);
        }
    else if (d[y]>d[x]) {

            y = get_ancestor(y, d[y]-d[x]);
        }


    int k=0;
    int a=x;
    int b=y;

    while(a!=b){

        a=s[k][x];
        b=s[k][y];

        if (a==b && k==0) return a;
        else  if (a==b && k!=0) {

            a=s[k-1][x];
            b=s[k-1][y];
            x=s[k-1][x];
            y=s[k-1][y];
            k=0;
        }
        else if (a!=b) ++k;
    }

    return a;
}

void DFS(int node) {

    for (auto x: G[node]) {

        d[x]=d[node]+1;
        DFS(x);
    }
}

void Solve() {

    f>>n>>m;

    int kmax= log2(n);

    build_ancestor(kmax);

    DFS(1);

    for (int querry=1; querry<=m; ++querry) {

        f>>x>>y;

        if (x==y) g<<x<<'\n';
        else g<<LCA(x,y)<<'\n';
    }
}

int main() {

    Solve();

    f.close(); g.close();
    return 0;
}