Cod sursa(job #1256780)

Utilizator vlady1997Vlad Bucur vlady1997 Data 6 noiembrie 2014 20:50:13
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.1 kb
        #include <cstdio>
        #include <vector>
        using namespace std;
        vector <int> g[100001];
        int tata[100001], euler[100001], nivel[100001], poz[100001], rmq[20][100001], lg[100001], m=1;
        void RMQ (void)
        {
            int i, j, x;
            for (i=1; (1<<i)<m; i++)
            {
                x=1<<(i-1);
                for (j=1; j<=m-(1<<i); j++)
                {
                    if (nivel[rmq[i-1][j]]<=nivel[rmq[i-1][j+x]]) rmq[i][j]=rmq[i-1][j];
                    else rmq[i][j]=rmq[i-1][j+x];
                }
            }
        }
        void dfs (int x, int p)
        {
            int i;
            for (i=0; i<g[x].size(); i++)
            {
                euler[++m]=g[x][i];
                nivel[m]=p+1;
                poz[g[x][i]]=m;
                dfs(g[x][i],p+1);
                euler[++m]=x;
                nivel[m]=p;
            }
        }
        int main()
        {
            int n, t, i, p, r, x, y, k, dif, sol;
            freopen("lca.in","r",stdin);
            freopen("lca.out","w",stdout);
            scanf("%d%d",&n,&t); lg[1]=0; euler[1]=1; nivel[1]=0;
            for (i=2; i<=n; i++)
            {
                scanf("%d",&tata[i]);
                g[tata[i]].push_back(i);
                lg[i]=lg[i/2]+1;
            }
            dfs(1,0);
            for (i=1; i<=m; i++) rmq[0][i]=i;
            RMQ();
            for (i=1; i<=t; i++)
            {
                scanf("%d%d",&p,&r); sol=-1;
                x=poz[p]; y=poz[r];
                if (x>y)
                {
                    int aux=x;
                    x=y; y=aux;
                }
                dif=y-x+1;
                k=lg[dif];
                if (nivel[rmq[k][x]]<=nivel[rmq[k][x+dif-(1<<k)]]) sol=rmq[k][x];
                else sol=rmq[k][x+dif-(1<<k)];
                printf("%d\n",euler[sol]);
            }
            fclose(stdin);
            fclose(stdout);
            return 0;
        }
//1 2 4 7 4 8 4 2 5 2 6 9 6 2 1 3 10 3 11 3 1
//0 1 2 3 2 3 2 1 2 1 2 3 2 1 0 1 2  1 2  1 0