Cod sursa(job #1487168)

Utilizator mihai_brodschiMihai Brodschi mihai_brodschi Data 16 septembrie 2015 11:34:02
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.81 kb
#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;

int n, m, a[200000][18],c[100002],p,l[100002],r,q,z[100002],s[100002],nru,k=1;
bool e;

void eul()
{
    for(int i=1; i<n; i++)
    {
        for(int j=1; j<n; j++)
            if(c[j]==i)
            {
                z[i]=j+1;
                break;
            }

    }
    while (c[p]==1)
    {
        p++;
    }
    p--;
    r=1;
    s[1]=1;
    a[k][0]=1;
    while(nru<p)
    {
        r++;
        if (z[s[r-1]])
        {
            s[r]=z[s[r-1]];
            k++;
            a[k][0]=s[r];
            if (a[k][0]==1)
                nru++;
            for(int i=z[s[r-1]]; i<=n; i++)
            {
                if(c[i]==c[z[s[r-1]]-1])
                {
                    z[s[r-1]]=i+1;
                    break;
                }
            }
            if(z[s[r-1]]==s[r])
                z[s[r-1]]=0;
        }
        else
        {
            k++;
            a[k][0]=s[r-2];
            if(a[k][0]==1)
                nru++;
            r-=2;
        }

    }
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d %d\n",&n,&m);
    l[1]=0;
    for(int i=2; i<=2*n-1; i++)
        l[i]=l[i/2]+1;
    c[0]=1;
    for(int i=1; i<n; i++)
        scanf("%d",&c[i]);
    a[1][0]=1;
    eul();
    for(int i=1; i<=n; i++)
        for(int j=1; j<=k; j++)
            if(a[j][0]==i)
                z[i]=j;
    p=1;
    for(int i=1; i<=l[2*n-1];i++)
    {
        p*=2;
        for (int j=1; j<=2*n-p ;j++)
            a[j][i]=min(a[j][i-1],a[j+p/2][i-1]);
    }
    for (int i=1; i<=m; i++)
    {
        scanf("%d %d",&q,&r);
        r=z[r];
        q=z[q];
        if(r<q)
            swap(r,q);
        p=pow(2,l[r-q+1]);
        printf("%d\n",min(a[q][l[r-q+1]],a[r-p+1][l[r-q+1]]));
    }
    return 0;
}