Cod sursa(job #1367464)

Utilizator ZeBuGgErCasapu Andreas ZeBuGgEr Data 1 martie 2015 21:30:07
Problema Lowest Common Ancestor Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 3.5 kb
#include<stdio.h>
#include<vector>

using namespace std;

int euler[300100],nivel[300100],p=1;
int pos[300100];
int lg[1000100];
int d[300100][50];
vector<int> *l;

void parc(int po,int niv)
{
    int t;
    if(pos[po]==0)
    {
        pos[po]=p;
    }
    euler[p]=po;
    nivel[p]=niv;
    p++;
    while(!l[po].empty())
    {
        t=l[po].back();
        l[po].pop_back();
        parc(t,niv+1);
        euler[p]=po;
        nivel[p]=niv;
        p++;
    }
}

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

    int n,m,t;
    fscanf(fin,"%d %d",&n,&m);
    l=new vector<int>[n+1];
    for(int i=2;i<=n;i++)
    {
        fscanf(fin,"%d",&t);
        l[t].push_back(i);
    }

    parc(1,0);

    /*for(int i=1;i<p;i++)
    {
        fprintf(fout,"%d ",euler[i]);
    }

    fprintf(fout,"\n");

    for(int i=1;i<p;i++)
    {
        fprintf(fout,"%d ",nivel[i]);
    }

    fprintf(fout,"\n");

    for(int i=1;i<=n;i++)
    {
        fprintf(fout,"%d ",pos[i]);
    }*/

    int temp,temp2;

    lg[0]=0;
    lg[1]=0;

    for(int i=2;i<=1000000;i++)
    {
        t=i;
        while(t%2==0)
        {
            t/=2;
        }
        if(t==1)
        {
            lg[i]=lg[i-1]+1;
        }
        else
        {
            lg[i]=lg[i-1];
        }
    }
    //fprintf(fout,"\n");

    for(int i=1;i<p;i++)
    {
        d[i][0]=i;
    }

    //fprintf(fout,"\n");

    for(int j=1;j<17;j++)
    {
        for(int i=1;i<p;i++)
        {
            if(nivel[d[i][j-1]]<=nivel[d[i+(1<<(j-1))][j-1]]&&i+(1<<(j-1))<p)
            {
                d[i][j]=d[i][j-1];
            }
            else if(i+(1<<(j-1))<p)
            {
                d[i][j]=d[i+(1<<(j-1))][j-1];
            }
        }
    }

    /*for(int i=1;i<p;i++)
    {
        for(int j=0;j<17;j++)
        {
            fprintf(fout,"%d ",d[i][j]);
        }
        fprintf(fout,"\n");
    }*/

    for(int i=0;i<m;i++)
    {
        fscanf(fin,"%d %d",&temp,&temp2);
        //fprintf(fout,"%d %d\n* %d %d\n",temp,temp2,pos[temp],pos[temp2]);
        if(pos[temp]<pos[temp2])
        {
            if(nivel[d[pos[temp]][lg[pos[temp2]-pos[temp]+1]]]<nivel[d[pos[temp2]-(1<<(lg[pos[temp2]-pos[temp]+1]))+1][lg[pos[temp2]-pos[temp]+1]]])
            {
                //fprintf(fout,"1_ %d %d\n",pos[temp],pos[temp2]-pos[temp]+1);
                fprintf(fout,"%d\n",euler[d[pos[temp]][lg[pos[temp2]-pos[temp]+1]]]);
            }
            else
            {
                //fprintf(fout,"2_ %d %d\n",pos[temp2]-(1<<(lg[pos[temp2]-pos[temp]+1]))+1,pos[temp2]-pos[temp]+1);
                fprintf(fout,"%d\n",euler[d[pos[temp2]-(1<<(lg[pos[temp2]-pos[temp]+1]))+1][lg[pos[temp2]-pos[temp]+1]]]);
            }
        }
        else
        {
            if(nivel[d[pos[temp2]][lg[pos[temp]-pos[temp2]+1]]]<nivel[d[pos[temp]-(1<<(lg[pos[temp]-pos[temp2]+1]))+1][lg[pos[temp]-pos[temp2]+1]]])
            {
                //fprintf(fout,"3_ %d %d\n",pos[temp2],pos[temp]-pos[temp2]+1);
                fprintf(fout,"%d\n",euler[d[pos[temp2]][lg[pos[temp]-pos[temp2]+1]]]);
            }
            else
            {
                //fprintf(fout,"4_ %d %d\n",pos[temp]-(1<<(lg[pos[temp]-pos[temp2]+1]))+1,pos[temp]-pos[temp2]+1);
                fprintf(fout,"%d\n",euler[d[pos[temp]-(1<<(lg[pos[temp]-pos[temp2]+1]))+1][lg[pos[temp]-pos[temp2]+1]]]);
            }
        }
    }
}