Cod sursa(job #1502026)

Utilizator retrogradLucian Bicsi retrograd Data 14 octombrie 2015 03:14:41
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.49 kb
#include <bits/stdc++.h>

using namespace std;

#define MAXN 100005

int Parent[MAXN], Lead[MAXN];
bool Viz[MAXN];

int G[MAXN], Nxt[MAXN], Fii[MAXN], Queries[MAXN];
int Sol[2*MAXN], Q[4*MAXN], NxtQ[4*MAXN];

int Find(int i) {
    if(!Lead[i]) return i;
    return Lead[i] = Find(Lead[i]);
}
void Union(int a, int b) {
    Lead[Find(a)] = Find(b);
}

void dfs(int node) {

    Parent[node] = node;
    for(int vec = G[node]; vec; vec = Nxt[vec]) {
        dfs(vec);
        Union(node, vec);
        Parent[Find(node)] = node;
    }

    Viz[node] = 1;

    for(int q = Queries[node]; q; q = NxtQ[q]) {
        if(Viz[Q[q]] && Sol[q / 2] == 0)
            Sol[q / 2] = Parent[Find(Q[q])];
    }
}

void addQ(int id, int a, int b) {
    NxtQ[id] = Queries[a];
    Queries[a] = id;
    Q[id] = b;
}

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

    int n, m, a, b;
    fin>>n>>m;

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

        Nxt[i] = G[a];
        G[a] = i;
    }

    while(m) {
        for(int i=1; i<=n; i++) {
            Lead[i] = Queries[i] = Parent[i] = Viz[i] = 0;
        }

        int lim = min(2*n, m);

        for(int i=1; i<=lim; i++) {
            fin>>a>>b;
            addQ(2*i, a, b);
            addQ(2*i+1, b, a);
        }

        dfs(1);

        for(int i=1; i<=lim; i++) {
            fout<<Sol[i]<<'\n';
            Sol[i] = 0;
        }

        m -= lim;
    }

    return 0;
}