Cod sursa(job #1501643)

Utilizator 2chainzTauheed Epps 2chainz Data 13 octombrie 2015 18:21:53
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.71 kb
#include<fstream>
#include<vector>
#include<cstdlib>
#include<ctime>
using namespace std;
ifstream in("heavypath.in");
ofstream out("heavypath.out");
const int Nmax = 100001;
vector<int> G[Nmax],So[Nmax],Ch[Nmax];
int N,M,h[Nmax],v[Nmax],A[4*Nmax],L[Nmax];
int K,pos[Nmax],pof[Nmax],cha[Nmax],tat[Nmax];
void he(int x,int l){
    h[x]=1,L[x]=l;
    for(vector<int>::iterator it=G[x].begin();it!=G[x].end();++it){
        if(!h[*it]){
            So[x].push_back(*it);
            he(*it,l+1),h[x]+=h[*it];
        }
    }
}
void dfs(int x,int k){
    Ch[k].push_back(x);
    pos[x]=Ch[k].size(),pof[x]=k;
    int mx=0,ch;
    if(So[x].size()){
        for(vector<int>::iterator it=So[x].begin();it!=So[x].end();++it){
            if(h[*it]>mx) mx=h[*it],ch=*it;
        }
        for(vector<int>::iterator it=So[x].begin();it!=So[x].end();++it){
            if(*it==ch) dfs(*it,k);
            else tat[++K]=x,dfs(*it,K);
        }
    }
}
void _update(int i,int st,int dr,int &w,int &val){
    if(st>=dr) A[i]=val;
    else{
        int mij=(st+dr)/2;
        if(w<=mij) _update(2*i,st,mij,w,val);
        else _update(2*i+1,mij+1,dr,w,val);
        A[i]=max(A[2*i],A[2*i+1]);
    }
}
void update(int c,int p,int val){
    p=cha[c]+p-1;
    _update(1,1,N,p,val);
}
int _query(int i,int st,int dr,int a,int b){
    if(a<=st && dr<=b) return A[i];
    int mij=(st+dr)/2;
    if(b<=mij) return _query(2*i,st,mij,a,b);
    if(a>mij) return _query(2*i+1,mij+1,dr,a,b);
    int a1=_query(2*i,st,mij,a,mij);
    int a2=_query(2*i+1,mij+1,dr,mij+1,b);
    return max(a1,a2);
}
int query(int c,int a,int b){
    return _query(1,1,N,cha[c]+a-1,cha[c]+b-1);
}
int solut(int x,int y){
    int sol=0;
    while(pof[x]!=pof[y]){
        if(L[tat[pof[x]]]<L[tat[pof[y]]]) swap(x,y);
        int a1=query(pof[x],1,pos[x]);
        sol=max(sol,a1);
        x=tat[pof[x]];
    }
    if(pos[x]>pos[y]) swap(x,y);
    int a1=query(pof[x],pos[x],pos[y]);
    sol=max(sol,a1);
    return sol;
}
int main(){
    in>>N>>M;
    for(int i=1;i<=N;i++) in>>v[i];
    int x,y;
    for(int i=1;i<N;i++){
        in>>x>>y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    int root=rand()%N+1;
    he(root,1),dfs(root,++K); cha[0]=1;
    for(int i=1;i<=K;i++) cha[i]=cha[i-1]+Ch[i-1].size();
    for(int i=1;i<=K;i++){
        for(vector<int>::iterator it=Ch[i].begin();it!=Ch[i].end();++it){
            update(pof[*it],pos[*it],v[*it]);
        }
    }
    for(int i=1;i<=M;i++){
        in>>x;
        if(x==0){
            in>>x>>y;
            update(pof[x],pos[x],y);
        }
        else{
            in>>x>>y;
            out<<solut(x,y)<<'\n';
        }
    }
    return 0;
}