Cod sursa(job #933214)

Utilizator PatrikStepan Patrik Patrik Data 29 martie 2013 18:16:03
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.78 kb
    #include<cstdio>
    #include<vector>
    using namespace std;
    #define MAX 100001
    #define pb push_back
    int N ,m, L[2*MAX] , poz[2*MAX] , lev[2*MAX] , K, M[2*MAX][20] , log[MAX];
    vector<int>G[MAX];

    void DFS(int nod , int l);
    void rmq();

    int main()
    {
        int x,aux,y,dim;
        freopen("lca.in" , "r" , stdin );
        freopen("lca.out" , "w" , stdout );
        scanf("%d%d" , &N , &m );
        for(int i = 2 ; i <= N ; ++i )
        {
            scanf("%d" , &x );
            G[x].pb(i);
        }
        DFS(1,0);
        rmq();
        /*for(int i = 1 ; i <= K ; ++i )
            printf("%d %d\n" , L[i] , lev[i]);*/
        for(;m;m--)
        {
            scanf("%d%d" , &x , &y);
            if(poz[x] > poz[y]){aux=x;x=y;y=aux;}
            dim = poz[y]-poz[x]+1;
            int k = log[dim];
            if(lev[M[poz[x]][k]] < lev[M[poz[y]-(1<<k)+1][k]])
                printf("%d\n" , L[M[poz[x]][k]] );
            else
                printf("%d\n" , L[M[poz[y]-(1<<k)+1][k]]);
        }
        return 0;
    }

    void DFS(int nod , int l)
    {
        L[++K] = nod;
        lev[K] = l;
        poz[nod] = K;
        for(int j = 0 ; j < (int)G[nod].size() ; ++j )
        {
            DFS(G[nod][j],l+1);
            L[++K] = nod;
            lev[K] = l;
        }
    }

    void rmq()
    {
        for(int j = 2 ; j <= K ; ++j )
            log[j] = log[j/2]+1;
        for(int i = 1 ; i <= K; ++i )
            M[i][0] = i;
        for(int j = 1 ; (1<<j)-1 < K ; ++j )
            for(int i = 1 ; i + (1<<j)-1 <= K ; ++i )
                if(lev[M[i][j-1]]<lev[M[i+(1<<(j-1))][j-1]])
                    M[i][j] = M[i][j-1];
                else M[i][j] = M[i+(1<<(j-1))][j-1];
    }