Cod sursa(job #2379643)

Utilizator NaritaandreiCNAINarita Andrei NaritaandreiCNAI Data 13 martie 2019 21:22:55
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.87 kb
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
FILE *f,*g;
int arb[200002];
struct graph
{
    int node,next;
}v[200002];
int rmq[45][200002];
int start[100002],log2[200002],poz[100002],rang[100002];
int n,m,k;
void read()
{   int y,k=0;
    fscanf(f,"%d %d",&n,&m);
    for(int i=2; i<=n; i++)
    {
        fscanf(f,"%d",&y);
        v[++k].node=y;
        v[k].next=start[i];
        start[i]=k;

        v[++k].node=i;
        v[k].next=start[y];
        start[y]=k;
    }
}
void euler(int nod)
{
    rmq[0][++k]=nod;
    if(!poz[nod])
        poz[nod]=k;
    for(int i=start[nod]; i; i=v[i].next)
    {
        if(!rang[v[i].node])
        {
            rang[v[i].node]=rang[nod]+1;
            euler(v[i].node);
            rmq[0][++k]=nod;
        }
    }
}
void logarithm()
{
    for(int i=2; i<=k; i++)
        log2[i]=log2[i/2]+1;
}
void build_rmq()
{   int pow;
    for(int i=1; i<=log2[k]; i++)
    {
        pow=1<<(i-1);
        for(int j=1; j<=k-pow+1; j++)
        {
            if(rang[rmq[i-1][j]]<rang[rmq[i-1][j+pow]])
                rmq[i][j]=rmq[i-1][j];
            else
                rmq[i][j]=rmq[i-1][j+pow];
        }
    }
}
void write(int a, int b)
{
    int z=log2[b-a+1];
    if(rang[rmq[z][a]]<rang[rmq[z][b-(1<<z)+1]])
        fprintf(g,"%d\n",rmq[z][a]);
    else
        fprintf(g,"%d\n",rmq[z][b-(1<<z)+1]);
}
void solve()
{   int x,y,a,b;
    rang[1]=1;
    euler(1);
    logarithm();
    build_rmq();
    for(int l=1; l<=m; l++)
    {
        fscanf(f,"%d %d",&x,&y);
        a=poz[y];
        b=poz[x];
        if(a<b)
            write(a,b);
        else
            write(b,a);
    }
}
int main()
{
    f=fopen("lca.in","r");
    g=fopen("lca.out","w");
    read();
    solve();
    //write();
    fclose(f);
    fclose(g);
    return 0;
}