Cod sursa(job #1461175)

Utilizator badea_adi1999Badea Adrian Catalin badea_adi1999 Data 14 iulie 2015 22:22:58
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.76 kb
#include <fstream>
#include <vector>
#include <cstdio>
#define nmax 100005
using namespace std;
vector <int> v[nmax];
int n,m,niv[nmax],viz[nmax],d[nmax];
int t[nmax],lg[nmax*4];
int l[19][nmax*4],nrl,prim[nmax];

void dfs(int x)
{
    int i,y;
    l[0][++nrl]=x;
    if (prim[x]==0)
        prim[x]=nrl;
    viz[x]=1;
    for (i=0;i<v[x].size();i++) {
        y=v[x][i];
        if (!viz[y]) {
            niv[y]=niv[x]+1;
            d[y]=d[x]+t[y];
            dfs(y);
            l[0][++nrl]=x;
        }
    }

}
#define strdim 1000000
int poz;
char s[strdim];

void read(int &num)
{
    num=0;
    while (s[poz]<'0'||s[poz]>'9')
        if (++poz==strdim)
            fread(s,1,strdim,stdin),poz=0;
    while (s[poz]>='0'&&s[poz]<='9') {
        num=num*10+s[poz]-'0';
        if (++poz==strdim)
            fread(s,1,strdim,stdin),poz=0;
    }
}
void rmq()
{
    int i,j,x,y;
    for (i=2;i<=nrl;i++)
        lg[i]=lg[i/2]+1;
    for (i=1;(1<<i)<=nrl;i++) {
        for (j=1;j+(1<<i)<=nrl;j++) {
            x=l[i-1][j];
            y=l[i-1][j+(1<<(i-1))];
            if (niv[x]<niv[y])
                l[i][j]=x;
            else
                l[i][j]=y;
        }
    }
}
int query(int x,int y)
{
    if (x>y)
        swap(x,y);
    int log=lg[y-x+1];
    int a=l[log][x],b=l[log][y-(1<<log)+1];
    if (niv[a]<niv[b])
        return a;
    return b;
}
int main()
{
    int i,j,x,y;

    freopen("lca.in","r",stdin);
    ofstream g("lca.out");
    fread(s,1,strdim,stdin);
    read(n);read(m);
    for (i=2;i<=n;i++) {
        read(x);
        v[x].push_back(i);
    }
    dfs(1);
    rmq();
    for (i=1;i<=m;i++) {
        read(x);read(y);
        g<<query(prim[x],prim[y])<<'\n';
    }
    return 0;
}