Cod sursa(job #1512864)

Utilizator serbanSlincu Serban serban Data 28 octombrie 2015 19:04:43
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.13 kb
#include <bits/stdc++.h>

using namespace std;

int t[100005], n, start;
bool viz[100005];
vector<int> L[100005];

vector< pair<int, int> > euler; //200 005
int first[100005];

FILE *g = fopen("lca.out", "w");

void dfs(int where, int level) {
    first[where] = euler.size() - 1;
    for(int i = 0; i < L[where].size(); i ++) {
        euler.push_back(make_pair(L[where][i], level + 1));
        dfs(L[where][i], level + 1);
        euler.push_back(make_pair(where, level));
    }
}

int M[800005];
void update(int node, int L, int R) {
    if(L == R) {
        M[node] = L;
        return ;
    }
    int mij = (R - L) / 2 + L;
    update(node * 2, L, mij);
    update((node * 2) + 1, mij + 1, R);

    if(euler[M[(node * 2) + 1]].second > euler[M[(node * 2)]].second)
            M[node] = M[(node * 2)];
    else M[node] = M[(node * 2) + 1];
}

int val, pval;
void ask(int node, int L, int R, int a, int b) {
    if(a <= L && R <= b) {
        if(euler[M[node]].second < pval)
            pval = euler[M[node]].second,
            val = euler[M[node]].first;
        return ;
    }
    int mij = (R - L) / 2 + L;
    if(a <= mij)
        ask(node * 2, L, mij, a, b);
    if(b > mij)
        ask(node * 2 + 1, mij + 1, R, a, b);
}

int lca(int a, int b) {
    if(a > b) {
        int aux = a;
        a = b;
        b = aux;
    }
    val = n + 1;
    pval = 1 << 30;
    ask(1, 1, n, a, b);
    return val;
}

int main()
{
    FILE *f = fopen("lca.in", "r");

    int m, x, y;
    fscanf(f, "%d %d", &n, &m);
    for(int i = 2; i <= n; i ++) {
        fscanf(f, "%d", &t[i]);
        viz[i] = true;
        L[t[i]].push_back(i);
    }
    for(int i = 1; i <= n; i ++) {
        if(!viz[i])
            start = i;
    }

    euler.push_back(make_pair(start, 0));
    dfs(start, 0);
    euler.push_back(make_pair(1 << 30, 1 << 30));
    n = euler.size() - 2;
    for(int i = 0; i <= 2 * n; i ++)
        M[i] = n + 1;

    update(1, 1, n);
    for(int i = 1; i <= m; i ++) {
        fscanf(f, "%d %d", &x, &y);
        fprintf(g, "%d\n", lca(first[x], first[y]));
    }
    return 0;
}