Cod sursa(job #2214815)

Utilizator RaduMirceaAndreiRadu Mircea Andrei RaduMirceaAndrei Data 20 iunie 2018 10:49:58
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.81 kb
# include <fstream>
# include <vector>
# define DIM 100010
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
vector<int> Lista[DIM],Lant[DIM],aint[DIM];
int v[DIM],nr[DIM],t[DIM],val[DIM],Poz[DIM],niv[DIM];
int nrLant,n,q,i,x,y,r,tp,idx,sol;
void dfs(int nc,int tata){
    nr[nc]=1;
    niv[nc]=niv[tata]+1;
    int maxim=0;
    int poz;
    for(int i=0;i<Lista[nc].size();i++){
        int nv=Lista[nc][i];
        if(nr[nv]==0){
            dfs(nv,nc);
            nr[nc]+=nr[nv];
            if(maxim<nr[nv]){
                maxim=nr[nv];
                poz=nv;
            }
        }
    }
    if(maxim==0){
        nrLant++;
        Lant[nrLant].push_back(nc);
        val[nc]=nrLant;
        Poz[nc]=0;
    }
    else{
        Lant[val[poz]].push_back(nc);
        val[nc]=val[poz];
        Poz[nc]=Lant[val[poz]].size()-1;
        for(int i=0;i<Lista[nc].size();i++){
            int nv=Lista[nc][i];
            if(nv!=tata&&nv!=poz)
                t[val[nv]]=nc;
        }
    }
}
void build(int nod,int st,int dr,int i){
    if(st==dr){
        aint[i][nod]=v[Lant[i][st]];
        return;
    }
    int mij=(st+dr)/2;
    build(2*nod,st,mij,i);
    build(2*nod+1,mij+1,dr,i);
    aint[i][nod]=max(aint[i][2*nod],aint[i][2*nod+1]);
}
void update(int nod,int st,int dr,int poz,int i){
    if(st==dr){
        aint[i][nod]=v[Lant[i][st]];
        return;
    }
    int mij=(st+dr)/2;
    if(poz<=mij)
        update(2*nod,st,mij,poz,i);
    else
        update(2*nod+1,mij+1,dr,poz,i);
    aint[i][nod]=max(aint[i][2*nod],aint[i][2*nod+1]);
}
void query(int nod,int st,int dr,int p,int u,int i){
    if(p<=st&&u>=dr){
        sol=max(sol,aint[i][nod]);
        return;
    }
    int mij=(st+dr)/2;
    if(p<=mij)
        query(2*nod,st,mij,p,u,i);
    if(u>mij)
        query(2*nod+1,mij+1,dr,p,u,i);
}
int solve(int x,int y){
    sol=0;
    while(val[x]!=val[y]){
        if(niv[t[val[x]]]<niv[t[val[y]]])
            swap(x,y);
        idx=val[x];
        query(1,0,Lant[idx].size()-1,Poz[x],Lant[idx].size()-1,idx);
        x=t[val[x]];
    }
    idx=val[x];
    query(1,0,Lant[idx].size()-1,min(Poz[x],Poz[y]),max(Poz[x],Poz[y]),idx);
    return sol;
}
int main () {
    fin>>n>>q;
    for(i=1;i<=n;i++)
        fin>>v[i];
    for(i=1;i<n;i++){
        fin>>x>>y;
        Lista[x].push_back(y);
        Lista[y].push_back(x);
    }
    dfs(1,0);
    for(i=1;i<=nrLant;i++){
        aint[i].resize(4*Lant[i].size());
        build(1,0,Lant[i].size()-1,i);
    }
    for(r=1;r<=q;r++){
        fin>>tp>>x>>y;
        if(tp==0){
            v[x]=y;
            idx=val[x];
            update(1,0,Lant[idx].size()-1,Poz[x],idx);
            continue;
        }
        fout<<solve(x,y)<<"\n";
    }
    return 0;
}