Cod sursa(job #710376)

Utilizator vendettaSalajan Razvan vendetta Data 9 martie 2012 15:44:08
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.17 kb
#include <fstream>
#include <vector>
#define nmax 32005

using namespace std;

vector<int> gf[nmax];
int n, M, P[nmax], D[nmax*2], Euler[nmax*2], Ord[nmax], arb[nmax<<4];
int A, B, rez, Nod, k, Max_sol=-1;

ifstream f("concurs.in");
ofstream g("concurs.out");

void citeste(){

    f >> n >> M;
    for(int i=1; i<=n; i++) f >> P[i];
    for(int i=1; i<n; i++){
        int x , y;
        f >> x >> y;
        gf[x].push_back(y);
    }

}

void dfs(int nod, int niv){

    ++k;
    D[k] = niv;
    Euler[k] = nod;
    Ord[nod] = k;

    for(int i=0; i<gf[nod].size(); i++){
        dfs(gf[nod][i], niv+1);
        ++k;
        D[k] = niv;
        Euler[k] = nod;
    }

}

void udpate(int nod, int st, int dr, int poz, int val){

    if (st == dr){
        arb[nod] = st;
        return ;
    }

    int mij = (st + dr) / 2;
    if (poz <= mij) udpate(nod*2, st, mij, poz, val);
        else udpate(nod*2+1, mij+1, dr, poz, val);

    arb[nod] = arb[nod*2];
    if(D[arb[nod]] > D[arb[nod*2+1]])
        arb[nod] = arb[nod*2+1];

}

void query(int nod, int st, int dr, int a, int b){

    if (a <= st && dr <= b){
        if (D[arb[nod]] < rez){
            rez = D[arb[nod]];
            Nod = arb[nod];
        //    return ;
        }
        return;
    }

    int mij = (st + dr) / 2;
    if (a <= mij) query(nod*2, st, mij, a, b);
    if (b > mij) query(nod*2+1, mij+1, dr, a, b);

}

void rezolva(){

    for(int i=1; i<=k; i++){
        udpate(1, 1, k, i, i);
    }

    for(int i=1; i<=M; i++){
        int x, y, X, Y;
        f >> X >> Y;
        x = Ord[X];
        y = Ord[Y];
        if (x > y){
            int aux = x;
            x = y;
            y = aux;
        }
        rez = (1<<29);
        query(1, 1, k, x, y);
        if (Max_sol < P[Nod]){
            Max_sol = P[Nod];
            A = X;
            B = Y;
        }else if (Max_sol == P[Nod]){
            if (A > X){
                A = X;
                B = Y;
            }
        }else if(Max_sol == P[Nod] && A == X && B > Y) B = Y;
    }

}

void scrie(){

    g << Max_sol << " " << A << " " << B << "\n";

}

int main(){

    citeste();

    dfs(1,1);
    rezolva();
    scrie();

    f.close();
    g.close();

    return 0;

}