Cod sursa(job #1512780)

Utilizator serbanSlincu Serban serban Data 28 octombrie 2015 17:06:02
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.41 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 rad;
int wh[700];

int lca(int l, int r) {
    if(l > r) {
        int aux = l; l = r; r = aux;}
    int poz = 0;
    while(poz < l)
        poz += rad;
    int where = euler.size() - 1;
    // inainte de bucati
    for(int i = l; i <= poz; i ++) {
        if(euler[where].second > euler[i].second) {
            where = i;
        }
    }
    poz ++;
    // bucatile de sqrt
    for(poz; poz + rad < r; poz += rad) {
        if(euler[where].second > euler[wh[poz / rad + 1]].second)
            where = wh[poz / rad + 1];
    }
    // dupa bucati
    for(int i = poz; i <= r; i ++) {
        if(euler[where].second > euler[i].second) {
            where = i;
        }
    }
    return euler[where].first;
}

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

    int m, x, y;
    fscanf(f, "%d %d", &n, &m);
    rad = sqrt(2 * n);
    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));

    int k = 1;
    n = euler.size() - 1;
    for(int i = 0; i < n; i += rad) {
        int lim = min(i + rad, n);
        int mn = 1 << 30;
        for(int j = i; j < lim; j ++) {
            if(mn > euler[j].second) {
                mn = euler[j].second;
                wh[k] = j;
            }
        }
        k ++;
    }/*
    for(int i = 1; i < k; i ++)
        fprintf(g, "%d ", wh[i]);

    for(int i = 1; i <= n; i ++)
        fprintf(g, "%d ", first[i]);
    fprintf(g, "\n");
    for(int i = 0; i < euler.size(); i ++)
        fprintf(g, "%d ", euler[i].first);
*/

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