Cod sursa(job #2410417)

Utilizator Andrei-27Arhire Andrei Andrei-27 Data 20 aprilie 2019 01:04:59
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.7 kb
/***
    sursa e copiata
    doar sa vad cat ia

***/

#include <bits/stdc++.h>
#define Nmax 100005
#define pb push_back

using namespace std;

vector <int> L[Nmax],Lant[Nmax],aint[Nmax];
int val[Nmax],n,nr_lant,nr_fii[Nmax];
int lvl[Nmax],wh[Nmax],pos[Nmax],Father[Nmax];

inline void dfs(int nod, int tata)
{
    int node=0;
    nr_fii[nod]=1;
    for(auto it : L[nod])
        if(it!=tata)
        {
            lvl[it]=lvl[nod]+1;
            dfs(it,nod);
            nr_fii[nod]+=nr_fii[it];
            if(nr_fii[it]>nr_fii[node]) node=it;
        }
    if(!node)
    {
        Lant[++nr_lant].pb(nod);
        wh[nod]=nr_lant;
        pos[nod]=1;
    }
    else
    {
        wh[nod]=wh[node];
        Lant[wh[nod]].pb(nod);
        pos[nod]=Lant[wh[nod]].size();
    }
    for(auto it : L[nod])
        if(it!=tata && it!=node)
            Father[wh[it]]=nod;
}

inline void upd(int ind, int nod, int st, int dr, int x, int val)
{
    if(st==dr)
    {
        aint[ind][nod]=val;
        return;
    }
    int mij=((st+dr)>>1);
    if(x<=mij) upd(ind,2*nod,st,mij,x,val);
    else upd(ind,2*nod+1,mij+1,dr,x,val);
    aint[ind][nod]=max(aint[ind][2*nod],aint[ind][2*nod+1]);
}

inline int qry(int ind, int nod, int st, int dr, int x, int y)
{
    if(st==x && y==dr) return aint[ind][nod];
    int mij=((st+dr)>>1);
    if(y<=mij) return qry(ind,2*nod,st,mij,x,y);
    else
        if(x>mij) return qry(ind,2*nod+1,mij+1,dr,x,y);
        else
            return max(qry(ind,2*nod,st,mij,x,mij),qry(ind,2*nod+1,mij+1,dr,mij+1,y));
}

inline void precompute()
{
    int i,j;
    for(i=1;i<=nr_lant;++i) aint[i].resize(Lant[i].size()*4 + 5);
    for(i=1;i<=nr_lant;++i)
        for(j=0;j<Lant[i].size();++j)
            upd(i,1,1,Lant[i].size(),j+1,val[Lant[i][j]]);
}

int main()
{
    int m,x,y,sol,tip,i;
    ifstream cin("heavypath.in");
    ofstream cout("heavypath.out");
    cin>>n>>m;
    for(i=1;i<=n;++i) cin>>val[i];
    for(i=1;i<n;++i)
    {
        cin>>x>>y;
        L[x].pb(y); L[y].pb(x);
    }
    lvl[1]=1; dfs(1,0);
    precompute();
    while(m--)
    {
        cin>>tip>>x>>y;
        if(!tip)
            upd(wh[x],1,1,Lant[wh[x]].size(),pos[x],y);
        else
        {
            sol=0;
            while(wh[x]!=wh[y])
            {
                if(lvl[Father[wh[x]]]<lvl[Father[wh[y]]])
                    swap(x,y);
                sol=max(sol,qry(wh[x],1,1,Lant[wh[x]].size(),pos[x],Lant[wh[x]].size()));
                x=Father[wh[x]];
            }
            sol=max(sol,qry(wh[x],1,1,Lant[wh[x]].size(),min(pos[x],pos[y]),max(pos[x],pos[y])));
            cout<<sol<<"\n";
        }
    }
    return 0;
}