Cod sursa(job #1481630)

Utilizator killer301Ioan Andrei Nicolae killer301 Data 4 septembrie 2015 22:40:11
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.05 kb
#include <cstdio>
#include <vector>
#include <cstring>

using namespace std;

const int nmax = 100000;

struct Node
{
    int dad;
    vector <int> sons;
};

int power[2*nmax+5];
int lvl[2*nmax+5];
int first[nmax+5];
int Rmq[30][2*nmax+5];

class GRAPH
{
private:
    int n, last;
    vector <int> a[nmax+5];
    vector <int> Euler;
public:
    GRAPH(int N)
    {
        last=0;n=N;
        memset(lvl, 0, sizeof(lvl));
        memset(first, 0, sizeof(first));
    }
    void push(int x, int y)
    {
        a[x].push_back(y);
    }
    void dfs(int nod, int level)
    {
        if(first[nod] == 0)first[nod] = Euler.size();
        lvl[Euler.size()] = level;
        Euler.push_back(nod);
        for(int i=0; i<a[nod].size(); i++)
        {
            dfs(a[nod][i], level+1);
            lvl[Euler.size()] = level;
            Euler.push_back(nod);
        }
    }
    void rmq()
    {
        for(int i=0; i<Euler.size(); i++)
            Rmq[0][i] = i;
        for(int i=1; (1<<i)<Euler.size(); i++)
            for(int j=0; j<Euler.size()-(1<<i); j++)
            {
                Rmq[i][j] = Rmq[i-1][j];
                if(Euler[Rmq[i-1][j+(1<<(i-1))]] < Euler[Rmq[i][j]])
                    Rmq[i][j] = Rmq[i-1][j+(1<<(i-1))];
            }
    }
    int lca(int x, int y)
    {
        if(first[x] > first[y])swap(x, y);
        int a = first[x];
        int b = first[y];
        int l = power[b-a+1];
        int ans = min(Euler[Rmq[l][a]], Euler[Rmq[l][b+1-(1<<l)]]);
        return ans;
    }
};

int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    for(int i=2; i<=2*nmax; i++)
        power[i] = power[i>>1]+1;
    int n, m;
    scanf("%d%d", &n, &m);
    GRAPH G(n);
    for(int i=1; i<n; i++)
    {
        int x;
        scanf("%d", &x);
        G.push(x, i+1);
    }
    G.dfs(1, 0);
    G.rmq();
    for(int i=0; i<m; i++)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        printf("%d\n", G.lca(x, y));
    }
    return 0;
}