Cod sursa(job #1257177)

Utilizator cernat.catallinFMI Cernat Catalin Stefan cernat.catallin Data 7 noiembrie 2014 13:03:04
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.1 kb
#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define Nmax 100005
#define Lgmax 20
#define trace(x) cerr << #x << ": " << x << '\n';

vector<vector<int>> Graph;
int euler[Nmax << 1];
int level[Nmax << 1];
int first[Nmax];
int rmq[Nmax << 1][Lgmax];
int lg[Nmax << 1];
int n, m, k;


void read(){
    int x;

    scanf("%d %d", &n, &m);
    Graph.resize(n + 1);
    for (int i = 2; i <= n; ++i){
        scanf("%d", &x);
        Graph[x].push_back(i);
    }
}

void dfs(int node, int lvl){
    vector<int>::iterator it;

    euler[++k] = node;
    level[k] = lvl;
    first[node] = k;
    
    for (it = Graph[node].begin(); it != Graph[node].end(); ++it){
        dfs(*it, lvl + 1);
        euler[++k] = node;
        level[k] = lvl;
    }
}

void create_rmq(){
    int l;

    for (int i = 2; i <= k; ++i)
        lg[i] = lg[i / 2] + 1;

    for (int i = 1; i <= k; ++i)
        rmq[i][0] = i;

    for (int j = 1; 1 << j <= k; ++j)
        for (int i = 1; i + (1 << j) - 1 <= k; ++i){
            l = 1 << (j - 1);
            if (level[rmq[i][j - 1]] < level[rmq[i + l][j - 1]])
                rmq[i][j] = rmq[i][j - 1];
            else
                rmq[i][j] = rmq[i + l][j - 1];
        }
}

void solve(){
    int x, y;
    int l;
    dfs(1, 0);

    // for (int i = 1; i <= k; ++i)
    //     printf("%d ", euler[i]);
    // printf("\n");
    // for (int i = 1; i <= k; ++i)
    //     printf("%d ", level[i]);
    // printf("\n");

    create_rmq();
    // for (int j = 1; 1 << j <= k; ++j)
    //     for (int i = 1; i + (1 << j) - 1 <= n; ++i){
    //         printf("%d "
    //     }
    //
    for (int i = 1; i <= m; ++i){
        scanf("%d %d", &x, &y);
        x = first[x];
        y = first[y];

        if (x > y)
            swap(x, y);
        l = lg[y - x + 1];

        if (level[rmq[x][l]] < level[rmq[y - (1 << l) + 1][l]])
            printf("%d\n", euler[rmq[x][l]]);
        else
            printf("%d\n", euler[rmq[y - (1 << l) + 1][l]]);
    }
}

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

    read();
    solve();
}