Cod sursa(job #3210555)

Utilizator SerbanCaroleSerban Carole SerbanCarole Data 6 martie 2024 17:15:53
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.84 kb
#include <fstream>
#include <vector>
using namespace std;
const int nmax = 1e5 + 1;
ifstream cin("heavypath.in");
ofstream cout("heavypath.out");
vector <int> g[nmax];
int n , m , x , y , v[nmax] , sz[nmax] , hvc[nmax], ind , poz[nmax] , tin[nmax] , tout[nmax] , tm;
int c[nmax] , t[nmax] , op;
struct segt
{
    int aint[4*nmax];
    void update(int nod , int st, int dr, int &new_value, int &poz)
    {
        if(st == dr) aint[nod] = new_value;
        else
        {
            int mj = (st+dr)/2;
            if(poz <= mj) update(nod*2,st,mj,new_value,poz);
            else update(nod*2+1,mj+1,dr,new_value,poz);
            aint[nod] = max(aint[nod*2],aint[nod*2+1]);
        }
    }
    int query(int nod , int st, int dr , int&qst, int&qdr)
    {
        if(qst<=st && dr<=qdr) return aint[nod];
        else
        {
            int val = -1;
            int mj = (st+dr)/2;
            if(qst<=mj) val = max(val,query(nod*2,st,mj,qst,qdr));
            if(qdr>mj) val = max(val,query(nod*2+1,mj+1,dr,qst,qdr));
            return val;
        }
    }
}arb;
bool isanc(int &x , int &y)
{
    return(tin[x]<=tin[y]&&tout[y]<=tout[x]);
}
void siz(int x , int p)
{
    sz[x] = 1;
    for(auto it : g[x])
    {
        if(it!=p)
        {
            siz(it,x);
            sz[x] += sz[it];
        }
    }
    for(auto it : g[x])
    {
        if(it!=p && sz[it]>sz[x]/2)
        {
            hvc[x] = it;
            break;
        }
    }
}
void hp(int x , int p , int cap)
{
    t[x] = p;
    c[x] = cap;
    tin[x] = ++tm;
    poz[x] = ++ind;
    arb.update(1,1,n,v[x],ind);
    if(hvc[x])
    {
        hp(hvc[x],x,cap);
    }
    for(auto it : g[x])
    {
        if(it == p || it == hvc[x]) continue;
        hp(it,x,it);
    }
    tout[x] = ++tm;
}
signed main()
{
    cin >> n >> m;
    for(int i = 1 ; i <= n ; ++i)
    {
        cin >> v[i];
    }
    for(int i = 1 ; i < n ; ++i)
    {
        cin >> x >> y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    siz(1,0);
    hp(1,0,1);
    for(int i = 1 ; i <= m ; ++i)
    {
        cin >> op >> x >> y;
        if(op == 0)
        {
            arb.update(1,1,n,y,poz[x]);
        }
        else
        {
            int mx = -1;
            while(true)
            {
                if(isanc(c[x],y)) break;
                mx = max(mx,arb.query(1,1,n,poz[c[x]],poz[x]));
                x = t[c[x]];
            }
            while(true)
            {
                if(isanc(c[y],x)) break;
                mx = max(mx,arb.query(1,1,n,poz[c[y]],poz[y]));
                y = t[c[y]];
            }
            int pmn = min(poz[x],poz[y]);
            int pmx = max(poz[x],poz[y]);
            mx = max(mx,arb.query(1,1,n,pmn,pmx));
            cout << mx << '\n';
        }
    }
    return 0;
}