Cod sursa(job #1955936)

Utilizator Train1Train1 Train1 Data 6 aprilie 2017 13:06:05
Problema Lowest Common Ancestor Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 3.91 kb
/*
#include <vector>
#include <fstream>
#include <iostream>

using namespace std;

#define MAX_N 100005
#define INF 0x3f3f3f3f

#define foreach(V) for(typeof (V).begin() it = (V).begin(); it != (V).end(); ++it)
#define nst (nod << 1)
#define ndr (nst | 1)
#define mij ((li + lf) >> 1)

int K, N, M, P;
int L[MAX_N << 1], H[MAX_N << 1],Lg[MAX_N << 1], First[MAX_N];
int A[MAX_N << 4], st, dr, sol, hsol;

vector <int> G[MAX_N];

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

void citire()
{
    fin >> N >> M;

    for(int i = 2; i <= N; ++i)
    {
        int x;
        fin >> x;
        G[x].push_back(i);
    }
}

void dfs(int nod, int lev)
{
    H[++K] = nod;
    L[K] = lev;
    First[nod] = K;

    foreach(G[nod])
    {
        dfs(*it, lev+1);

        H[++K] = nod;
        L[K] = lev;
    }
}

void build(int nod, int li, int lf)
{
    if(li == lf)
    {
        A[nod] = li;
        return;
    }

    build(nst, li, mij);
    build(ndr, mij+1, lf);

    if(L[A[nst]] <= L[A[ndr]])
        A[nod] = A[nst];
    else
        A[nod] = A[ndr];
}

void query(int nod, int li, int lf)
{
    if(st <= li && lf <= dr)
    {
        if(L[A[nod]] < hsol)
            sol = H[A[nod]],
            hsol = L[A[nod]];
        return;
    }

    if(st <= mij) query(nst, li, mij);
    if(mij < dr)  query(ndr, mij+1, lf);
}

int lca(int x, int y)
{
    st = First[x], dr = First[y];
    if(st > dr) swap(st, dr);
    sol = hsol = INF;
    query(1, 1, K);

    return sol;
}

int main()
{
    citire();
    dfs(1, 0);
    build(1, 1, K);
    for(int i = 1; i <= K; i++) {
        cout<<A[i]<<' ';
    }
    while(M--)
    {
        int x, y;
        fin >> x >> y;
        fout << lca(x, y) << "\n";
    }
}
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#define NMax 100001
#define MAXNR 999999999
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector <int> v [NMax];
vector <pair <int, int> > rEuler;
int x, y, n, m, pos, nr = 1;
int First[NMax];
pair <int, int> val;
pair <int, int> A[NMax << 4];
void DF(int R, int nivel) {
    rEuler.push_back(make_pair(R, nivel));
    First[R] = nr;
    nr++;
    for(int i = 0; i < v[R].size(); i++) {
        DF(v[R][i], nivel + 1);
        rEuler.push_back(make_pair(R, nivel));
        nr++;
    }
}
pair <int, int> sol;
void adauga(int nod, int st, int dr) {
    if(st == dr) {
        A[nod] = val;
    } else{
        int mij = (st + dr) / 2;
        if(pos > mij) {
            adauga(2 * nod + 1, mij + 1, dr);
        } else {
            adauga(2 * nod, st, mij);
        }
        if(A[2*nod].second > A[2*nod + 1].second) {
            A[nod] = A[2 * nod + 1];
        } else {
            A[nod] = A[2 * nod];
        }
    }
}
int Left, Right;
void query(int nod, int st, int dr) {
    if (st >= Left && dr <= Right) {
        if(sol.second > A[nod].second) {
            sol = A[nod];
        }
    } else {
        int mij = (st + dr) / 2;
        if (mij >= Left) query(2 * nod, st, mij);
        if (mij < Right) query(2 * nod + 1, mij + 1, dr);
    }
}
int main()
{
    fin>>n>>m;
    for(int i = 2; i <= n; i++) {
        fin>>x;
        v[x].push_back(i);
    }
    rEuler.push_back(make_pair(0, 0));
    DF(1, 0);
    for(int i = 1 ; i <= nr; i++) {
        val = rEuler[i];
        pos = i;
        adauga(1, 1, nr);
    }
    nr--;
    for(int i = 1; i <= nr; i++) {
        cout<<A[i].second<<" ";
    }
    for(int i = 1; i <= m; i++) {
        fin>>x>>y;
        Left = First[x];
        Right = First[y];
        if(First[x] > First[y]) {
            Left = First[y];
            Right = First[x];
        }
        sol.first = MAXNR;
        sol.second = MAXNR;
        query(1, 1, nr);
        fout<<sol.first<<'\n';
    }
    fin.close();
    fout.close();
    return 0;
}