Cod sursa(job #2197894)

Utilizator emanuel_rRamneantu Emanuel emanuel_r Data 23 aprilie 2018 03:16:04
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.69 kb
#include <bits/stdc++.h>

using namespace std;

template <typename T>
class LCA{
public:
    vector<vector<pair<int, T> > > G;
    function<T(T,T)> func;
    vector<int> L, Log, use;
    vector<vector<int> > A;
    vector<vector<T> > V;
    bool indexed;
    int n, root;
    T acc;

    LCA(int n, int root, decltype(G)& Graph, bool idx, function<T(T,T)> f, T acc) :
            n(n), root(root), G(move(Graph)), indexed(idx), func(f), acc(acc), use(n+1), L(n+1), A(n+1), V(n+1) {};

    void dfs(int node, int father, T cost){
        L[node] = L[father] + 1;
        A[node].emplace_back(father);
        V[node].emplace_back(cost);
        use[node] = 1;

        for(auto& it : G[node])
            if(!use[it.first])
                dfs(it.first, node, it.second);
    }

    void build() {
        dfs(root, 0, 0);

        Log.emplace_back(0);
        Log.emplace_back(0);
        for(int i = 2; i <= n; i++)
            Log.emplace_back(Log[i/2] + 1);

        A[0].emplace_back(0);
        V[0].emplace_back(0);
        for(int step = 1; step <= Log[n]; step++)
            for(int i = indexed; i < n + indexed; i++) {
                A[i].emplace_back(A[A[i][step - 1]][step - 1]);
                V[i].emplace_back(func(V[i][step - 1], V[V[i][step - 1]][step - 1]));
            }

    }

    pair<int, T> query(int x, int y){
        if(L[x] < L[y])
            swap(x, y);
        int maxstep, diff;
        T fold = acc;
        while(L[x] > L[y]){
            diff = L[x] - L[y];
            maxstep = Log[diff];
            fold = func(V[x][maxstep], fold);
            x = A[x][maxstep];
        }
        for(int step = Log[n]; step >= 0; step--){
            if(A[x][step] == A[y][step])
                continue;
            fold = func(V[x][step], fold);
            fold = func(V[y][step], fold);
            x = A[x][step];
            y = A[y][step];
        }
        if(x != y){
            fold = func(V[x][0], fold);
            fold = func(V[y][0], fold);
            x = A[x][0];
        }
        return make_pair(x, fold);
    }
};

vector<vector<pair<int, bool> > > G;
LCA<bool> *L;
int n, m;

int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);

    scanf("%d %d", &n, &m);
    int t;
    G.resize(n + 1);

    for(int i = 2; i <= n; i++){
        scanf("%d", &t);
        G[t].emplace_back(i, 0);
    }
    L = new LCA<bool>(n, 1, G, 1, [](bool a, bool b){return 0;}, 0);
    L->build();

    int x, y;
    int ance, val;

    for(int i = 1; i <= m; i++){
        scanf("%d %d", &x, &y);
        tie(ance, val) = L->query(x, y);
        printf("%d\n", ance);
    }
    return 0;
}