Cod sursa(job #1122552)

Utilizator PatrikStepan Patrik Patrik Data 25 februarie 2014 18:47:01
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.88 kb
    #include<cstdio>
    #include<vector>
    using namespace std;
    #define MAX 100001
    #define pb push_back
    int N ,M,K,lev[MAX] , poz[4*MAX] , L[4*MAX] , k  , log[4*MAX] , R[4*MAX][20];
    vector<int>G[MAX] ;

    void read();
    void rmq();
    void solve();
    void DFS(int nod , int l);
    int query(int a , int b);

    int main()
    {
        read();
        DFS(1,0);
        rmq();
        solve();
        return 0;
    }

    void read()
    {
        int x;
        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);
        }
    }

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

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

    void solve()
    {
        int x , y;
        for(int i = 1 ; i <= M ; ++i )
        {
            scanf("%d%d" , &x , &y );
            printf("%d\n" , query(poz[x],poz[y]));
        }
    }

    int query(int a , int b)
    {
        int aux , p;
        if(a > b){aux = a ; a = b;b = aux;}
        p = log[b-a+1];
        if(lev[R[a][p]] < lev[R[b-(1<<p)+1][p]])
            return R[a][p];
        return R[b-(1<<p)+1][p];
    }