Cod sursa(job #2984816)

Utilizator RaresPoinaruPoinaru-Rares-Aurel RaresPoinaru Data 24 februarie 2023 23:00:28
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.27 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");

const int MAXN=100010;

int n,m,a[MAXN],nrf[MAXN],visitat[MAXN],lant[MAXN],radacina[MAXN],poz[MAXN],aint[4*MAXN];
int nivel[MAXN],tata[MAXN];
int k;
vector <int> g[MAXN];

void Dfs (int node){
    if (visitat[node]==1)
        return;
    visitat[node]=1;
    int rez=1;
    for (int i=0;i<g[node].size ();++i){
        if (visitat[g[node][i]]==0){
            nivel[g[node][i]]=nivel[node]+1;
            tata[g[node][i]]=node;
            Dfs (g[node][i]);
            rez+=nrf[g[node][i]];
        }
    }

    nrf[node]=rez;
}

void Crearelant (int node){
    if (visitat[node]==2)
        return;
    visitat[node]=2;
    poz[node]=++k;
    int maxx=0,nodeurm=-1;
    for (int i=0;i<g[node].size ();++i){
        int x=g[node][i];
        if (visitat[x]==2)
            continue;
        if (nrf[x]>maxx){
            maxx=nrf[x];
            nodeurm=x;
        }
    }
    if (nodeurm==-1)
        return ;
    radacina[nodeurm]=radacina[node];
    Crearelant (nodeurm);
    for (int i=0;i<g[node].size ();++i){
        int x=g[node][i];
        if (visitat[x]==2)
            continue;
        if (x!=nodeurm){
            Crearelant (x);
        }
    }
}


void Update (int node, int l, int r, int pos, int val){
    if (l==r)
        aint[node]=val;
    else{
        int mij=(l+r)/2;
        if (pos<=mij)
            Update (2*node,l,mij,pos,val);
        else
            Update (2*node+1,mij+1,r,pos,val);
        aint[node]=max (aint[2*node],aint[2*node+1]);
    }
}

int Query (int node, int l, int r, int ql, int qr){
    if (l>qr || r<ql || l>r)
        return -1;
    if (ql<=l and r<=qr)
        return aint[node];
    int mij=(l+r)/2;
    int rez1=Query (2*node,l,mij,ql,qr);
    int rez2=Query (2*node+1,mij+1,r,ql,qr);
    return max (rez1,rez2);
}

int Query2 (int x, int y){
    int rez;
    if (radacina[x]==radacina[y]){
        if (nivel[x]>nivel[y])
            swap (x,y);
        rez=Query (1,1,n,poz[x],poz[y]);
    }
    else{
        if(nivel[radacina[x]]<nivel[radacina[y]])
            swap(x,y);
        if (x==6 and y==1){
            //fout <<poz[];
        }
        rez=Query(1,1,n,poz[radacina[x]],poz[x]);
        x=tata[radacina[x]];
        rez=max(rez,Query2(x,y));
    }
    return rez;
}


int main()
{
    fin >>n>>m;
    for (int i=1;i<=n;++i)
        fin >>a[i];

    for (int i=1;i<=n-1;++i){
        int x,y;
        fin >>x>>y;
        g[x].push_back (y);
        g[y].push_back (x);
    }

    Dfs (1);


    /*for (int i=1;i<=n;++i){
        fout <<nrf[i]<<' ';
    }
    fout <<'\n';*/

    for (int i=1;i<=n;++i)
        radacina[i]=i;


    Crearelant (1);
    /*for (int i=1;i<=n;++i){
        fout <<poz[i]<<' ';
    }
    fout <<'\n';
    for (int i=1;i<=n;++i){
        fout <<tata[i]<<' ';
    }*/

    for (int i=1;i<=n;++i)
        Update (1,1,n,poz[i],a[i]);

    for (int i=1;i<=m;++i){
        int r,x,y;
        fin >>r>>x>>y;
        if (r==0){
            Update (1,1,n,poz[x],y);
        }
        else{
            fout <<Query2 (x,y)<<' ';
        }
    }
    fin.close ();
    fout.close ();
    return 0;
}