Cod sursa(job #2369167)

Utilizator usureluflorianUsurelu Florian-Robert usureluflorian Data 5 martie 2019 21:32:15
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2 kb
#include <bits/stdc++.h>
using namespace std;
ifstream f ("heavypath.in");
ofstream g ("heavypath.out");
const int nmax=1e5+3;
int n,t,x,y,lvl[nmax],sz[nmax],ind[nmax],caz,usu[nmax],k,m,val[nmax],poz[nmax],tir[2*nmax];
vector <int> v[nmax],path[nmax];
void dfs(int nod,int ant)
{
    lvl[nod]=lvl[ant]+1;
    sz[nod]=1;
    int bst=0;
    for(int i=0;i<v[nod].size();++i)
    {
        int urm=v[nod][i];
        if(urm==ant) continue;
        dfs(urm,nod);
        sz[nod]+=sz[urm];
        if(sz[urm]>sz[bst]) bst=urm;
    }
    for(int i=0;i<v[nod].size();++i)
    {
        int urm=v[nod][i];
        if(urm!=ant&&urm!=bst) usu[ind[urm]]=nod;
    }
    if(!bst) ind[nod]=++k;
    else ind[nod]=ind[bst];
    path[ind[nod]].push_back(nod);
}
void update(int t,int x)
{
    t+=n;
    tir[t]=x;
    for(;k>1;k>>=1) tir[k>>1]=max(tir[k],tir[k^1]);
}
int gioto(int x,int y)
{
    int ans=0;
    x+=n;
    y+=n;
    for(;x<y;x>>=1,y>>=1)
    {
        if(x&1) ans=max(ans,tir[x++]);
        if(y&1) ans=max(ans,tir[--y]);
    }
    return ans;
}
int querry(int x,int y)
{
    int sol=0;
    while(ind[x]!=ind[y])
    {
        if(lvl[usu[ind[x]]]<lvl[usu[ind[y]]]) swap(x,y);
        sol=max(sol,gioto(poz[x],poz[path[ind[x]].back()]+1));
        x=usu[ind[x]];
    }
    if(poz[x]>poz[y]) swap(x,y);
    return max(sol,gioto(poz[x],poz[y]+1));
}
int main()
{
    ios::sync_with_stdio(false);
    f>>n>>m;
    for(int i=1;i<=n;++i) f>>val[i];
    for(int i=1;i<n;++i)
    {
        f>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs(1,0);
    int nr=0;
    for(int i=1;i<=k;++i)
    {
        for(int j=0;j<path[i].size();++j)
        {
            int urm=path[i][j];
            poz[urm]=++nr;
            tir[nr+n]=val[urm];
        }
    }
    for(int i=n;i;--i) tir[i]=max(tir[i<<1],tir[i<<1|1]);
    while(m--)
    {
        f>>caz>>x>>y;
        if(!caz) update(poz[x],y);
        else g<<querry(x,y)<<'\n';
    }
    return 0;
}