Cod sursa(job #2915302)

Utilizator alexdumitruAlexandru Dumitru alexdumitru Data 22 iulie 2022 12:52:08
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.76 kb
#include <bits/stdc++.h>

//#define int long long

using namespace std;

const int NMAX=100005;

void myswap(int &a, int &b)
{
    a=a^b;
    b=a^b;
    a=a^b;
}

int mymin(int a, int b)
{
    return (a<b?a:b);
}

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

const int mod = 1000000007;

int n,i,j,cnt;
vector<pair<int,int> > g[NMAX];

int eu[NMAX*2],h[NMAX];

int l2[2*NMAX],lev[2*NMAX];

int rmq[2*NMAX][20];

int father[NMAX];

int sz[NMAX];

bool isonlant[NMAX];

bool vis[NMAX];

int catepelant;

vector<pair<int,int> > g2[NMAX];

void euler(int nod, int l, int dad=0)
{
    father[nod]=dad;
    eu[++cnt]=nod;
    lev[cnt]=l;
    if(!h[nod])h[nod]=cnt;
    for(auto x:g[nod])
    {
        if(x.first==dad)continue;
        euler(x.first,l+1,nod);
        eu[++cnt]=nod;
    }
}

void build()
{
    for(i=1;i<n*2;i++)
        rmq[i][0]=eu[i];
    for(i=2;i<=n*2;i++)
        l2[i]=l2[i>>1]+1;
    int p=1;
    for(j=1;(1<<j)<=2*n;j++)
    {
        p<<=1;
        for(i=1;i+p-1<=2*n;i++)
            rmq[i][j]=mymin(rmq[i][j-1],rmq[i+p/2][j-1]);
    }
}

int qr(int x, int y)
{
    int l=l2[y-x+1];
    return mymin(rmq[x][l],rmq[y-(1<<l)+1][l]);
}


int lca(int a, int b)
{
    if(h[a]>h[b])
        myswap(a,b);
    return qr(h[a],h[b]);
}



void elcea()
{
    ifstream fin1("lca.in");
    ofstream fout1("lca.out");
    int q;
    fin1>>n>>q;
    for(i=2;i<=n;i++)
    {
        int x;
        fin1>>x;
        g[x].push_back({i,0});
        g[i].push_back({x,0});
    }
    euler(1,1);
    build();
    while(q--)
    {
        int a,b;
        fin1>>a>>b;
        fout1<<lca(a,b)<<'\n';
    }
}


signed main()
{

    elcea();
    return 0;

    return 0;
}