Cod sursa(job #1963972)

Utilizator tudi98Cozma Tudor tudi98 Data 12 aprilie 2017 22:46:31
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.89 kb
#include <fstream>
#include <vector>
using namespace std;

#define PER(i,a) for (int i = a-1; i >= 0; i--)
#define REP(i,a) for (int i = 0; i < a; i++)
#define FOR(i,a,b) for (int i = a; i <= b; i++)
#define ROF(i,a,b) for (int i = a; i >= b; i--)
#define FOREACH(it,x) for (__typeof((x).begin()) it = (x).begin(); it != (x).end(); it++)
#define all(x) (x).begin(),(x).end()
#define UNIQUE(x) sort(all(x)),(x).erase(unique(all(x)),(x).end())
#define ll long long
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define SZ(x) ((int)(x).size())

const int Nmax = 1e5;

int n,m;
int lg2[Nmax*2+1],T[Nmax+1];
vector<int> G[Nmax+1];
int E[Nmax*2+1],idE = 0;
int First[Nmax+1];
int lvl[Nmax+1];
int rmq[20][Nmax*2+1];

void dfs(int node)
{
    E[++idE] = node;
    First[node] = idE;
    FOREACH(it,G[node]) {
        lvl[*it] = lvl[node] + 1;
        dfs(*it);
        E[++idE] = node;
    }
}

void Build_LCA()
{
    lg2[0] = lg2[1] = 0;
    FOR(i,2,Nmax*2) lg2[i] = lg2[i-1] + ((i&(i-1)) == 0);
    lvl[1] = 1;
    dfs(1);
    FOR(i,1,2*n-1) rmq[0][i] = E[i];
    for (int i = 1; (1<<i) <= 2*n-1; i++)
        for (int j = 1; j + (1<<i) - 1 <= 2*n-1; j++) {
            int j1 = j,j2 = j + (1<<i-1);
            if (lvl[rmq[i-1][j1]] < lvl[rmq[i-1][j2]])
                rmq[i][j] = rmq[i-1][j1];
            else rmq[i][j] = rmq[i-1][j2];
        }
}

int lca(int x,int y)
{
    if (First[x] > First[y]) swap(x,y);
    x = First[x]; y = First[y];
    int step = lg2[y - x + 1];
    int ret = rmq[step][x];
    if (lvl[ret] > lvl[rmq[step][y-(1<<step)+1]])
        ret = rmq[step][y-(1<<step)+1];
    return ret;
}

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

    fin >> n >> m;
    FOR(i,2,n) {
        fin >> T[i];
        G[T[i]].pb(i);
    }

    Build_LCA();

    REP(i,m) {
        int x,y; fin >> x >> y;
        fout << lca(x,y) << "\n";
    }
}