Cod sursa(job #2985340)

Utilizator Silviu_StefanStefan Silviu Silviu_Stefan Data 26 februarie 2023 11:57:10
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.16 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int n;
const int MAXN=100000;
char buff[4096];
int pbuf=4095;
void readbuff(){
    pbuf=0;fin.read(buff,4095);
}
int citire(){
    int nr=0;
    if(pbuf==4095){
        readbuff();
    }
    while(buff[pbuf]<'0'||buff[pbuf]>'9'){
        pbuf++;
        if(pbuf==4095){
            readbuff();
        }
    }
    while(buff[pbuf]>='0'&&buff[pbuf]<='9'){
        nr=nr*10+buff[pbuf]-'0';pbuf++;
        if(pbuf==4095){
            readbuff();
        }
    }
    return nr;
}
int v[MAXN+5];
vector<int>G[MAXN+5];
int nivel[MAXN+5],heavy[MAXN+5];
int inceput[MAXN+5],pozitie[MAXN+5];
int parinte[MAXN+5];
int poz=0;
int DFS(int nod,int ant){
    int lungnod=1,maxlung=0;heavy[nod]=-1;
    parinte[nod]=ant;
    for(int i=0;i<G[nod].size();i++){
        if(G[nod][i]!=ant){
            nivel[G[nod][i]]=nivel[nod]+1;
            int lung=DFS(G[nod][i],nod);
            lungnod+=lung;
            if(lung>maxlung){
                maxlung=lung;
                heavy[nod]=G[nod][i];
            }
        }
    }
    return lungnod;
}
void descompune(int nod,int ant,int cap){
    inceput[nod]=cap;
    poz++;pozitie[nod]=poz;
    if(heavy[nod]!=-1){
        descompune(heavy[nod],nod,cap);
    }
    for(int i=0;i<G[nod].size();i++){
        if(G[nod][i]!=ant&&G[nod][i]!=heavy[nod]){
            descompune(G[nod][i],nod,G[nod][i]);
        }
    }
}
int aint[4*MAXN+5];
void update(int nod,int st,int dr,int poz,int val){
    if(st==dr){
        aint[nod]=val;return;
    }
    int mij=(st+dr)/2;
    if(poz<=mij){
        update(2*nod,st,mij,poz,val);
    }
    else if(mij<poz){
        update(2*nod+1,mij+1,dr,poz,val);
    }
    aint[nod]=max(aint[2*nod],aint[2*nod+1]);
}
int maxim=0;
void query(int nod,int st,int dr,int a,int b){
    if(a<=st&&dr<=b){
        maxim=max(maxim,aint[nod]);return;
    }
    int mij=(st+dr)/2;
    if(a<=mij){
        query(2*nod,st,mij,a,b);
    }
    if(mij+1<=b){
        query(2*nod+1,mij+1,dr,a,b);
    }
}
int query_interv(int x,int y){
    int rez=0;
    while(inceput[x]!=inceput[y]){
        if(nivel[inceput[x]]<nivel[inceput[y]]){
            swap(x,y);
        }
        maxim=0;query(1,1,n,min(pozitie[inceput[x]],pozitie[x]),max(pozitie[inceput[x]],pozitie[x]));
        rez=max(rez,maxim);
        x=parinte[inceput[x]];
    }
    maxim=0;query(1,1,n,min(pozitie[x],pozitie[y]),max(pozitie[x],pozitie[y]));
    rez=max(rez,maxim);
    return rez;
}
int main()
{
    int m,a,b;n=citire();m=citire();
    for(int i=1;i<=n;i++){
        v[i]=citire();
    }
    for(int i=1;i<=n-1;i++){
        a=citire();b=citire();
        G[a].push_back(b);
        G[b].push_back(a);
    }
    nivel[1]=1;DFS(1,0);
    descompune(1,0,1);
    for(int i=1;i<=n;i++){
        update(1,1,n,pozitie[i],v[i]);
    }
    int t;
    for(int i=1;i<=m;i++){
        t=citire();a=citire();b=citire();
        if(t==0){
            update(1,1,n,pozitie[a],b);
        }
        else if(t==1){
            fout<<query_interv(a,b)<<'\n';
        }
    }
    return 0;
}