Cod sursa(job #2839181)

Utilizator BalasaRaduBalasa Radu BalasaRadu Data 25 ianuarie 2022 13:50:18
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.93 kb
#include <bits/stdc++.h>
using namespace std;

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

const int dim=100009;

struct MaximSegmentTree{
    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));
    }
}aint;

vector<int>v[dim];

int val[dim];
int sz[dim],heavy[dim],head[dim];///sz[i]=lungimea subgrafului lui i,heavy[i]=urmatorul nod din lant,head[i]=capul lantului din care face parte i
int parent[dim],depth[dim];///parent[i]=parintele lui i,depth[i]=adancimea lui i in arborele initial

void dfs_size(int x,int tata){
    int max_size_child=0;
    parent[x]=tata;
    depth[x]=depth[tata]+1;
    sz[x]=1;
    for(int y:v[x]){
        if(y!=parent[x]){
            dfs_size(y,x);
            sz[x]+=sz[y];
            if(sz[y]>max_size_child){
                max_size_child=sz[y];
                heavy[x]=y;
            }
        }
    }
}

int total,poz_aint[dim];///poz_aint[i]=pozitia pe care o are i in aint

void HPD(int x,int h){
    poz_aint[x]=++total;
    head[x]=h;
    if(heavy[x]){
        HPD(heavy[x],h);
    }
    for(int y:v[x]){
        if(y!=parent[x]&&y!=heavy[x]){
            HPD(y,y);
        }
    }
}

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);

    for(int i=1;i<=n;i++){
        aint.update(1,1,n,poz_aint[i],val[i]);
    }

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