Cod sursa(job #1521518)

Utilizator papinubPapa Victor papinub Data 10 noiembrie 2015 16:36:39
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.38 kb
# include <cstdio>
# include <vector>
using namespace std;
FILE *f=freopen("lca.in","r",stdin);
FILE *g=freopen("lca.out","w",stdout);

const int bufferDIM=10001;
const int NMAX=100001;
class inputReader{

    char buffer[bufferDIM];
    int pos;

public:

    bool digit(char c)
    {
        return ('0'<=c && c<='9');
    }

    void getbuffer()
    {
        pos=0;
        fread(buffer,1,bufferDIM,stdin);
    }

    void getint(int &numar)
    {
        numar=0;

        while (!digit(buffer[pos]))
        {
            if (++pos==bufferDIM)
                getbuffer();
        }

        while (digit(buffer[pos]))
        {
            numar= numar*10 + buffer[pos] - '0';
            if (++pos==bufferDIM)
                getbuffer();
        }
    }
}cin;

int n,m,k;

vector <int> G[NMAX];
int H[2*NMAX]; // parcurgere euleriana
int L[2*NMAX]; // nivelul nodurilor din parcurgere
int first[NMAX]; // pozitia in parcurgere cand un nod apare prima oara
int lg[2*NMAX];
int rmq[20][2*NMAX];

void read()
{
    cin.getbuffer();
    cin.getint(n);
    cin.getint(m);

    for (int i=2;i<=n;i++)
    {
        int x;
        cin.getint(x);
        if (i!=x) G[x].push_back(i);
    }
}

void euler(int nod, int nivel)
{
    H[++k]=nod;
    L[k]=nivel;
    first[nod]=k;

    for (unsigned int i=0;i<G[nod].size();i++)
    {
        euler(G[nod][i],nivel+1);

        H[++k]=nod;
        L[k]=nivel;
    }
}

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

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

    for (int i=1; (1<<i)< k; i++)
    {
        for (int j=1;j<= k - (1<<i); j++)
        {
            int l=1<<(i-1);
            rmq[i][j]=rmq[i-1][j];
            if (L[rmq[i-1][j]]>L[rmq[i-1][j+l]])
                rmq[i][j]=rmq[i-1][j+l];
        }
    }
}
int lca(int x,int y)
{
    if (first[x]>first[y]) swap(x,y);
    int dif= first[y] - first[x] + 1;
    int put= lg[dif];

    int sol=rmq[put][first[x]];

    if (L[rmq[put][first[x]]]>L[rmq[put][first[y]-(1<<put) +1]])
        sol=rmq[put][first[y]-(1<<put) + 1];

    return H[sol];
}

void solve()
{
    for (int i=1;i<=m;i++)
    {
        int x,y;
        cin.getint(x);
        cin.getint(y);
        printf("%d\n",lca(x,y));
    }
}
int main()
{
    read();
    euler(1,0);
    rmqu();
    solve();
    return 0;
}