Cod sursa(job #1536989)

Utilizator bogdan10bosBogdan Sitaru bogdan10bos Data 26 noiembrie 2015 20:27:08
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.42 kb
#include <bits/stdc++.h>

#define INF (1 << 30)
#define LLINF (1LL << 62)
#define mod 666013

using namespace std;

class Reader
{
private:
    char buff[100805];
    int buffer, cnt;

public:
    Reader()
    {
        buffer = 1 << 15;
        cnt = buffer - 1;
    }

    char gChar()
    {
        if(++cnt == buffer)
        {
            cnt = 0;
            fread(buff, buffer, 1, stdin);
        }
        return buff[cnt];
    }

    int gInt()
    {
        int nr = 0;
        char ch = gChar();
        while(ch < '0' || '9' < ch)
            ch = gChar();
        while('0' <= ch && ch <= '9')
        {
            nr = nr * 10 + ch - '0';
            ch = gChar();
        }
        return nr;
    }
};
Reader rdr;

int n, m, k, R, i, x, y, fth;
int ap[300005], lstap[100005], lvl[100005];
int aint[1000005];

vector <int> v[100005];

void Euler(int nod)
{
    ap[++k] = nod;
    lstap[nod] = k;
    if(v[nod].size() == 0)
        return;

    vector <int> :: iterator it;
    for(it = v[nod].begin(); it != v[nod].end(); it++)
    {
        int nxt = *it;
        lvl[nxt] = lvl[nod] + 1;
        Euler(nxt);

        ap[++k] = nod;
        lstap[nod] = k;
    }
}

int minlvl(int a, int b)
{
    if(lvl[a] < lvl[b])
        return a;
    return b;
}

void B(int nod, int st, int dr)
{
    if(st == dr)
    {
        aint[nod] = ap[st];
        return;
    }

    int mij = st + (dr - st) / 2;
    B(nod * 2, st, mij);
    B(nod * 2 + 1, mij + 1, dr);

    aint[nod] = minlvl(aint[nod * 2], aint[nod * 2 + 1]);
}

void Q(int nod, int st, int dr, int sti, int dri)
{
    if(sti <= st && dr <= dri)
    {
        R = minlvl(R, aint[nod]);
        return;
    }

    int mij = st + (dr - st) / 2;
    if(sti <= mij)
        Q(nod * 2, st, mij, sti, dri);
    if(mij < dri)
        Q(nod * 2 + 1, mij + 1, dr, sti, dri);
}


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

    n = rdr.gInt();
    m = rdr.gInt();

    for(i = 2; i <= n; i++)
    {
        fth = rdr.gInt();
        v[fth].push_back(i);
    }

    lvl[1] = 0;
    lvl[n + 1] = INF;
    Euler(1);
    B(1, 1, k);

    while(m--)
    {
        x = rdr.gInt();
        y = rdr.gInt();

        R = n + 1;
        Q(1, 1, k, min(lstap[x], lstap[y]) , max(lstap[x], lstap[y]));
        printf("%d\n", R);
    }

    return 0;
}