Cod sursa(job #2646223)

Utilizator ionanghelinaIonut Anghelina ionanghelina Data 31 august 2020 13:48:41
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.51 kb
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>

using namespace std;

const int maxN=(2e5)+5;
const int maxL=(2e5)+5;

int de=0;
int lvl[maxN],euler[maxL],tst,n,k,x,y,rmq[21][maxL],firstAp[maxN],loga[maxL];
vector<int> v[maxN],lcas;
bool seen[maxN];

bool cmp(int a,int b)
{
    return lvl[a]>lvl[b];
}
void dfs(int nod,int niv)
{
    lvl[nod]=niv;
    euler[++de]=nod;
    seen[nod]=1;
    if(!firstAp[nod]) firstAp[nod]=de;

    for(auto it:v[nod])
    {
        if(seen[it]) continue;
        dfs(it,niv+1);
        euler[++de]=nod;
    }

}

inline void buildRmq()
{
    for(int i=1;i<=de;i++)
        rmq[0][i]=euler[i];

    for(int i=1;i<=19;i++)
    {
        for(int j=1;j<=de;j++)
            if( (j+(1<<(i-1)))>de) rmq[i][j]=rmq[i-1][j];
                else
            if(lvl[rmq[i-1][j]]<lvl[rmq[i-1][j+(1<<(i-1))]]) rmq[i][j]=rmq[i-1][j];
                else rmq[i][j]=rmq[i-1][j+(1<<(i-1))];
    }
}

inline int lca(int x,int y)
{
    x=firstAp[x];
    y=firstAp[y];
    if(x>y) swap(x,y);

    int len=(y-x+1);

    int ans=rmq[loga[len]][x];
    int dif=len-(1<<loga[len]);

    if(lvl[ans]>lvl[rmq[loga[len]][x+dif]]) ans=rmq[loga[len]][x+dif];

    return ans;
}

void dfs2(int nod)
{
    seen[nod]=1;
    for(auto it:v[nod])
        if(!seen[it] && lvl[it]<lvl[nod]) dfs2(it);
}
int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);

   // scanf("%d",&tst);
   tst=1;

    for(int i=2;i<maxL;i++)
        loga[i]=loga[i>>1]+1;

    while(tst--)
    {
        scanf("%d%d",&n,&k);
       // printf("%d\n",k);

        for(int i=1;i<=n;i++)
            v[i].clear();

        for(int i=1;i<n;i++)
        {
   //         scanf("%d%d",&x,&y);
     //       v[x].push_back(y);
       //     v[y].push_back(x);
            scanf("%d",&x);
            v[x].push_back(i+1);
        }

        de=0;

        memset(seen,0,sizeof(seen));
        memset(firstAp,0,sizeof(firstAp));

        dfs(1,0);
     //   printf("%d\n",de);


      //  for(int i=1;i<=de;i++)
       //     printf("%d ",euler[i]);

        buildRmq();
        lcas.clear();

        while(k--)
        {
            scanf("%d%d",&x,&y);
            lcas.push_back(lca(x,y));
        }
        for(auto it:lcas)
            printf("%d\n",it);

       /** sort(lcas.begin(),lcas.end(),cmp);

       // for(auto it:lcas)
         //   printf("%d ",it);

        memset(seen,0,sizeof(seen));

        int sol=0;

        for(auto it:lcas)
            if(!seen[it]) dfs2(it),sol++;


        printf("%d\n",sol);**/

    }

    return 0;
}