Cod sursa(job #2028651)

Utilizator DenisONIcBanu Denis Andrei DenisONIc Data 28 septembrie 2017 11:32:41
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.54 kb
#include <bits/stdc++.h>
#define Nmax 100006
using namespace std;

int n,P[Nmax],S[Nmax],fst[Nmax],t,u,v,q,nr,NRA[Nmax],x,y;
bool R[Nmax];

struct edge{
    int nod;
    bool p,s;
};

vector<edge> V[Nmax];
vector<pair<int,int> > E;
pair<int,int> rmq[21][Nmax*2];

void dfs(int nod,int nr)
{
    NRA[nod] = nr;
    for (auto it : V[nod])
    {
        P[it.nod] = P[nod] + it.p;
        S[it.nod] = S[nod] + it.s;
        dfs(it.nod,nr);
    }
}

void euler(int nod,int niv)
{
    fst[nod] = E.size();
    E.push_back({nod,niv});
    for (auto it : V[nod])
    {
        euler(it.nod,niv+1);
        E.push_back({nod,niv});
    }
}

int LCA(int a,int b)
{
    int x = log2(abs(fst[b]-fst[a]));
    if (rmq[x][min(fst[a],fst[b])].second<=rmq[x][max(fst[a],fst[b]) - (1<<x) + 1].second)
        return rmq[x][min(fst[a],fst[b])].first;
    return rmq[x][max(fst[a],fst[b]) - (1<<x) + 1].first;
}

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

    cin>>n>>q;
    for (int i=2;i<=n;i++)
    {
        scanf("%d",&x);
        if (x==-1)
        {
            R[i] = true;
            continue;
        }
        V[x].push_back({i,(y==1),(y==0)});
    }
    R[1] = true;

    for (int i=1;i<=n;i++)
        if (R[i]==true)
        {
            //dfs(i,++nr);
            euler(i,1);
        }

    int mx = log2(E.size());
    for (int i=0;i<=mx;i++)
        for (int j=0;j<E.size()-(1<<i)+1;j++)
        {
            if (i==0)
            {
                rmq[i][j] = E[j];
                continue;
            }
            if (rmq[i-1][j].second>rmq[i-1][j+(1<<(i-1))].second)
                rmq[i][j] = rmq[i-1][j+(1<<(i-1))];
            else
                rmq[i][j] = rmq[i-1][j];
        }

    for (int i=1;i<=q;i++)
    {
        scanf("%d%d",&x,&y);
        cout<<LCA(x,y)<<'\n';
    }

    /*cin>>q;
    for (int i=1;i<=q;i++)
    {
        cin>>t>>u>>v;
        if (t==1)
        {
            if (NRA[v]==NRA[u] && LCA(v,u)==u && S[u]-S[v]==E[fst[u]].second - E[fst[v]].second && v!=u)
                cout<<"YES\n";
            else
                cout<<"NO\n";
        }
        else
        {
            int x;
            if (NRA[v] == NRA[u])
                x = LCA(v,u);
            if (NRA[v] == NRA[u] && P[x]-P[v]==E[fst[x]].second - E[fst[v]].second && S[x]-S[u]==E[fst[x]].second - E[fst[u]].second && v!=u)
                cout<<"YES\n";
            else
                cout<<"NO\n";
        }
    }*/

    return 0;
}