Cod sursa(job #948394)

Utilizator roots4Irimia Alexandru Gabriel roots4 Data 10 mai 2013 09:49:53
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.95 kb
#include<fstream>
#include<vector>
 
using namespace std;
 
#define max_n 100100
 
ifstream f("heavypath.in");
ofstream g("heavypath.out");
 
vector<int> L[max_n];
vector<int> Lant[max_n];
struct aib{
    int max;
    aib *st , *dr;
}*A[max_n];
 
int V[max_n] , CLant[max_n] , PLant[max_n] , S[max_n] , T[max_n] , Niv[max_n];
int op , x , y , v_max , k , n , m;
int D[max_n];
 
void read(){
    int a , b;
    f>>n>>m;
     
    for(register int i = 1 ; i <= n ; i++)
        f>>V[i];
     
    for(register int i = 1 ; i < n ; i++){
        f>>a>>b;
        L[a].push_back(b);
        L[b].push_back(a);
    }
     
}
 
void dfs(int nod , int niv , int tata){
    int nod2 , nod_max , maxim = -1;
    S[nod] = 1; Niv[nod] = niv; T[nod] = tata;
     
    for(unsigned int i = 0 ; i < L[nod].size() ; i++){
        nod2 = L[nod][i];
        if( nod2 == tata )
            continue;
        dfs(nod2 , niv + 1 , nod);
        S[nod] += S[nod2];
        if(S[nod2] > maxim) maxim = S[nod2] , nod_max = nod2;
    }
     
    if( L[nod].size() == 1 && nod != 1 ){
        Lant[++k].push_back(1);
        Lant[k].push_back(nod); D[k]++ ; CLant[nod] = k; PLant[nod] = D[k];
    }
    else{
        int lant = CLant[nod_max];
        Lant[lant].push_back(nod); D[lant]++; CLant[nod] = lant; PLant[nod] = D[lant];
    }
     
} 
 
inline int vMax(int a , int b){
    return a>b?a:b;
}
 
void create(aib *T , int st , int dr , int lant){
    if(st == dr)
        T->max = V[Lant[lant][st]];
    else{
        int mid = ((st + dr) >> 1);
        T->st = new aib; T->dr = new aib;
        create(T->st , st , mid , lant);
        create(T->dr , mid+1 , dr , lant);
        T->max = vMax(T->st->max , T->dr->max);
    }
}
 
void form_aib(){
     
    for(int i = 1 ; i <= k ; i++){
        A[i] = new aib;
        create(A[i] , 1 , D[i] , i);
    }
     
}
 
void update(aib *T , int st , int dr , int poz){
    if(st == dr && st == poz)
        T->max = V[x];
    else{
        int mid = ((st + dr) >> 1);
        if(poz <= mid)
            update(T->st , st , mid , poz);
        else
            update(T->dr , mid + 1 , dr , poz);
        T->max = vMax(T->st->max , T->dr->max);
    }
}
 
bool intersectie(int st , int dr , int a , int b){
    if(a >= st && a <= dr) return 1;
    if(b >= st && b <= dr) return 1;
    if(st >= a && st <= b) return 1;
    if(dr >= a && dr <= b) return 1;
    return 0;
}
 
void querry(aib *T , int st , int dr , int a , int b){
    if(st >= a && dr <= b)
        v_max = vMax(v_max , T->max);
    else{
        int mid = ((st + dr) >> 1);
        if(intersectie(st , mid , a , b))
            querry(T->st , st , mid , a , b);
        if(intersectie(mid+1 , dr , a , b))
            querry(T->dr , mid+1 , dr , a , b);
    }
}
 
void solve(){
     
    while(m--){
        f>>op>>x>>y;
        switch(op){
        case 0:
            V[x] = y;
            update( A[CLant[x]] , 1 , D[CLant[x]] , PLant[x] );
            break;
        default:
             
            int l1 = CLant[x] , l2 = CLant[y] ; v_max = -1;
             
            while(l1 != l2){
                if(Niv[Lant[l1][D[l1]]] < Niv[Lant[l2][D[l2]]]){
                    querry(A[l2] , 1 , D[l2] , PLant[y] , D[l2]);
                    y = T[Lant[l2][D[l2]]];
                }
                else{
                    querry(A[l1] , 1 , D[l1] , PLant[x] , D[l1]);
                    x = T[Lant[l1][D[l1]]];
                }
                l1 = CLant[x] ; l2 = CLant[y];
            }
             
            int p1 = PLant[x] , p2 = PLant[y];
            if(p2 < p1)  swap(p1 , p2);
             
            querry(A[l1] , 1 , D[l1] , p1 , p2);
             
            g<<v_max<<"\n";
             
            break;
        }
    }
     
}
 
int main(){
     
    read();
     
    dfs(1 , 1 , 0);
     
    form_aib();
     
    solve();
     
    return 0;
}