Cod sursa(job #581134)

Utilizator andrey932Andrei andrey932 Data 13 aprilie 2011 19:58:30
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.9 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
#define MAXN 100005

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

vector<int> graf[MAXN];
int i,j,t[MAXN],n,m,a,b;
int euler[2*MAXN],euler_niv[2*MAXN],rmq[20][MAXN],ap[2*MAXN];

void preg_lca() {
    int prec;
    euler[1]=1;
    euler_niv[1]=1;
    rmq[0][1]=1;
    ap[1]=1;
    for(i=2;i<2*n;i++) {
        prec=euler[i-1];
        if (!graf[prec].empty()) {
            euler[i]=graf[prec].back();
            graf[prec].pop_back();
            euler_niv[i]=euler_niv[i-1]+1;
        }
        else {
            euler[i]=t[prec];
            euler_niv[i]=euler_niv[i-1]-1;
        }
        if (ap[euler[i]]==0) {ap[euler[i]]=i;}
        rmq[0][i]=i;
    }

    for(i=1;(1<<i)<2*n;i++) {
        for(j=1;j+(1<<i)<=2*n;j++) {
            if (euler_niv[rmq[i-1][j]]<=euler_niv[rmq[i-1][j+(1<<(i-1))]]) {
                rmq[i][j]=rmq[i-1][j];
            }
            else {
                rmq[i][j]=rmq[i-1][j+(1<<(i-1))];
            }
        }
    }
}

int rmqf(int a, int b) {
    if (a>b) swap(a,b);
    if (a==b) return a;
    int x=b-a+1,l=0;
    while (x>0) {l++; x>>=1;}
    if (euler_niv[rmq[l][a]]<=euler_niv[rmq[l][b-(1<<l)+1]]) {
        return rmq[l][a];
    }
    else return rmq[l][b-(1<<l)+1];
}

int lca(int x, int y) {
    int lc;
    if (x==y) return x;
    cout<<x<<"("<<ap[x]<<")   "<<y<<"("<<ap[y]<<")\n";
    lc=rmqf(ap[x],ap[y]);
    return euler[lc];
}






int main()
{
    fin>>n>>m;
    for(i=2;i<=n;i++) {
        fin>>t[i];
        graf[t[i]].push_back(i);
    }
    preg_lca();

    for(i=0;i<5;i++) {
        for(j=1;j<=2*n;j++) {
            cout<<euler_niv[rmq[i][j]]<<" ";
        }
        cout<<"\n";
    }
    for(i=1;i<=m;i++) {
        fin>>a>>b;
        fout<<lca(a,b)<<"\n";
    }

    fout.close();
    return 0;
}