Cod sursa(job #1932966)

Utilizator Marius7122FMI Ciltea Marian Marius7122 Data 20 martie 2017 11:36:52
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.64 kb
#include <stdio.h>
#include <vector>
#define N 100005
#define log 18
using namespace std;

vector<int> g[N];
int n,m,i,j,a,b,q;
int lvl[N],euler[2*N],ap[N],rmq[log][2*N],log2[2*N];  ///rmq[j][i]=nodul cu lvl minim dintre nodurile din euler[k], k de la i la i+2^j
bool viz[N];

int min(int a,int b)
{
    if(a<b)
        return a;
    return b;
}
void dfs(int x,int l)
{
    int i;

    viz[x]=true;
    lvl[x]=l;
    euler[++q]=x;
    ap[x]=q;

    for(i=0;i<g[x].size();i++)
        if(!viz[g[x][i]])
        {
            dfs(g[x][i],l+1);
            euler[++q]=x;
        }
}
int query(int x,int y)
{
    int p=log2[y-x+1];
    return min(rmq[p][x],rmq[p][y-(1<<p)+1]);
}

int main()
{
    FILE *f1,*f2;
    f1=fopen("lca.in","r");
    f2=fopen("lca.out","w");

    fscanf(f1,"%d%d",&n,&m);
    for(i=2;i<=n;i++)
    {
        fscanf(f1,"%d",&a);
        g[i].push_back(a);
        g[a].push_back(i);
    }

    dfs(1,0);

    rmq[0][1]=euler[1];
    for(i=2;i<=q;i++)
    {
        rmq[0][i]=euler[i];
        log2[i]=log2[i/2]+1;
    }

    for(j=1;(1<<j)<=q;j++)
        for(i=1;i<=q;i++)
        {
            if(lvl[rmq[j-1][i]]<lvl[rmq[j-1][i+(1<<(j-1))]])
                rmq[j][i]=rmq[j-1][i];
            else
                rmq[j][i]=rmq[j-1][i+(1<<(j-1))];
        }

    while(m--)
    {
        fscanf(f1,"%d%d",&a,&b);
        if(ap[a]>ap[b])
            swap(a,b);

        fprintf(f2,"%d\n",query(ap[a],ap[b]));
    }


    /*for(j=0;(1<<j)<=q;j++)
    {
        for(i=1;i<=q;i++)
            printf("%d ",lvl[rmq[j][i]]);
        printf("\n");
    }*/

    return 0;
}