Cod sursa(job #2180365)

Utilizator remus88Neatu Remus Mihai remus88 Data 20 martie 2018 20:23:42
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.52 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, int k) {

    if (s[k][x]==s[k][y] && k==0) return s[k][x];

    else if (s[k][x]==s[k][y]) return LCA(s[k-1][x],s[k-1][y],0);

    else return LCA(x,y,k+1);
}

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 (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]);
        }

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

int main() {

    Solve();

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