Cod sursa(job #1087752)

Utilizator harababurelPuscas Sergiu harababurel Data 19 ianuarie 2014 20:19:58
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.91 kb
#include <iostream>
#include <fstream>
#include <vector>
#define nmax 100005
#define mmax 2000005
#define inf (1<<30)
using namespace std;

vector <int> son[nmax];
int Euler[2*nmax], level[2*nmax], pos[nmax];
int n, m, x, y, Sid, Slevel;

int Hid[8*nmax], Hlevel[8*nmax];

void dfs(int curr, int h) {
    Euler[++Euler[0]] = curr;
    level[++level[0]] = h;
    pos[curr] = Euler[0];

    if(son[curr].size() == 0) return;

    for(int i=0; i<son[curr].size(); i++) {
        dfs(son[curr][i], h+1);
        Euler[++Euler[0]] = curr;
        level[++level[0]] = h;
    }
}

void build(int node, int lo, int hi) {
    if(lo == hi) {
        Hid[node] = Euler[lo];
        Hlevel[node] = level[lo];
        return;
    }
    int mid = (lo + hi) >> 1;
    build(2*node, lo, mid);
    build(2*node+1, mid+1, hi);

    Hid[node] = Hid[2*node];
    Hlevel[node] = Hlevel[2*node];
    if(Hlevel[2*node+1] < Hlevel[2*node]) {
        Hid[node] = Hid[2*node+1];
        Hlevel[node] = Hlevel[2*node+1];
    }
}

void query(int node, int lo, int hi, int a, int b) {
    if(a <= lo && hi <= b) {
        if(Hlevel[node] < Slevel) {
            Slevel = Hlevel[node];
            Sid = Hid[node];
        }
        return;
    }
    int mid = (lo + hi) >> 1;
    if(a <= mid) query(2*node, lo, mid, a, b);
    if(mid < b)  query(2*node+1, mid+1, hi, a, b);
}

int main() {
    ifstream f("lca.in");
    ofstream g("lca.out");

    f>>n>>m;
    for(int i=2; i<=n; i++) {
        f>>x;
        son[x].push_back(i);
    }
    dfs(1, 1);
    build(1, 1, Euler[0]);

    for(int i=1; i<=m; i++) {
        f>>x>>y;
        Sid = Slevel = inf;

        query(1, 1, Euler[0], min(pos[x], pos[y]), max(pos[x], pos[y]));
        g<<Sid<<"\n";
    }

    //for(int i=1; i<=Euler[0]; i++) g<<Euler[i]<<" "; g<<"\n";
    //for(int i=1; i<=level[0]; i++) g<<level[i]<<" "; g<<"\n";

    return 0;
}