Cod sursa(job #2839136)

Utilizator BalasaRaduBalasa Radu BalasaRadu Data 25 ianuarie 2022 13:15:05
Problema Heavy Path Decomposition Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.19 kb
#include <bits/stdc++.h>
#define dbg cout<<"OK"<<endl;
using namespace std;

ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

const int dim=100009;

vector<int>v[dim];

int sz[dim],parent[dim],depth[dim],val[dim];

struct SegmentTreeMaxim{
    int aint[4*dim];
    void update(int nod,int tl,int tr,int poz,int val){
        if(tl==tr){
            aint[nod]=val;
            return;
        }
        int tm=(tl+tr)/2;
        if(poz<=tm){
            update(2*nod,tl,tm,poz,val);
        }
        else{
            update(2*nod+1,tm+1,tr,poz,val);
        }
        aint[nod]=max(aint[2*nod],aint[2*nod+1]);
    }
    int query(int nod,int tl,int tr,int l,int r){
        if(l==tl && r==tr){
            return aint[nod];
        }
        int tm=(tl+tr)/2;
        if(r<=tm){
            return query(2*nod,tl,tm,l,r);
        }
        if(l>tm){
            return query(2*nod+1,tm+1,tr,l,r);
        }
        return max(query(2*nod,tl,tm,l,tm),query(2*nod+1,tm+1,tr,tm+1,r));
    }
}A;

void dfs_size(int x,int tata){

    sz[x]=1;
    depth[x]=depth[tata]+1;

    for(int y:v[x]){
        if(y!=tata){
            dfs_size(y,x);
            sz[x]+=sz[y];
            parent[y]=x;
        }
    }
}

int nr_comp,comp[dim],poz_aint[dim];
vector<int>c[dim];///nodurile care fac parte din componenta i

void HPD(int x,bool schimba,int comp_tata){///generare lanturi HPD
    int comp_locala;
    if(schimba){
        nr_comp++;
        comp_locala=nr_comp;
    }
    else{
        comp_locala=comp_tata;
    }
    c[comp_locala].push_back(x);
    comp[x]=comp_locala;
    for(int y:v[x]){
        if(y!=parent[x]){
            if(sz[y]>sz[x]/2){
                HPD(y,0,comp_locala);
            }
            else{
                HPD(y,1,comp_locala);
            }
        }
    }
}

signed main(){
    int n,q;
        fin>>n>>q;
    for(int i=1;i<=n;i++){
        fin>>val[i];
    }
    for(int i=2;i<=n;i++){
        int x,y;
        fin>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }

    dfs_size(1,0);
    HPD(1,1,0);

    int total=0;
    for(int i=1;i<=nr_comp;i++){
        for(int x:c[i]){
            total++;
            poz_aint[x]=total;
            A.update(1,1,n,total,val[x]);
        }
    }

    while(q--){
        int op;
            fin>>op;
        if(op==0){
            int poz,val;
            fin>>poz>>val;
            A.update(1,1,n,poz_aint[poz],val);
        }
        else{
            int l,r;
            fin>>l>>r;
            int ans=0;
            if(depth[l]<depth[r]){
                swap(l,r);
            }
            while(c[comp[l]][0]!=c[comp[r]][0]){
                ans=max(ans,A.query(1,1,total,poz_aint[c[comp[r]][0]],poz_aint[r]));
                if(parent[c[comp[r]][0]])
                    r=parent[c[comp[r]][0]];
                if(depth[c[comp[l]][0]]>depth[c[comp[r]][0]]){
                    swap(l,r);
                }
            }
            if(depth[l]>depth[r]){
                swap(l,r);
            }
            ans=max(ans,A.query(1,1,total,poz_aint[l],poz_aint[r]));
            fout<<ans<<'\n';
        }
    }
}