Cod sursa(job #1828327)

Utilizator MithrilBratu Andrei Mithril Data 13 decembrie 2016 08:51:04
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.61 kb
#include <bits/stdc++.h>
#define NMAX 100010
#define wow pair<int, int>
using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");
int n,m,x,y,z,K;
int firstPos[NMAX];
wow parcurgere[NMAX<<1]; ///depth,node
wow A[NMAX<<2];
vector<int> G[NMAX];

void DFS(int,int);
void build(int,int,int);
wow query(int,int,int,int,int);

int main()
{
    fin>>n>>m;
    for(int i=1; i<=n-1; i+=1)
    {
        fin>>z;
        G[z].push_back(i+1);
    }
    DFS(1,0);
    build(1,1,K);

    for(int i=1; i<=m; i+=1)
    {
        fin>>x>>y;
        wow answer=query(1,1,K,firstPos[min(x,y)],firstPos[max(x,y)]);
        fout<<answer.second<<'\n';
    }
    return 0;
}

void DFS(int node, int depth)
{
    parcurgere[++K]=make_pair(depth,node);
    firstPos[node] = K;

    if(G[node].size())
    {
        for(auto i:G[node])
        {
            DFS(i, depth+1);

            parcurgere[++K]=make_pair(depth,node);
        }
    }
}

void build(int node, int st, int dr)
{

    if(st==dr)
    {
        A[node]=parcurgere[st];
        return;
    }

    int mid=(st+dr)>>1,leftNode=node<<1,rightNode=node<<1|1;

    build(leftNode, st, mid);
    build(rightNode, mid+1, dr);

    A[node]=min(A[leftNode],A[rightNode]);
}

wow query(int node, int st, int dr, int x, int y)
{
    if(x <= st && dr <= y) return A[node];

    int mid=(st+dr)>>1,leftNode=node<<1,rightNode=node<<1|1;

    if(y<=mid) return query(leftNode,st,mid,x,y);
    else if(x>mid) return query(rightNode,mid+1,dr,x,y);
    else return min(query(leftNode,st,mid,x,y), query(rightNode,mid+1,dr,x,y));
}