Cod sursa(job #3292766)

Utilizator matei__bBenchea Matei matei__b Data 9 aprilie 2025 11:49:32
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.68 kb
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 
#define ll long long
#define ull unsigned long long
#define ld long double
#define chad char
#define mod 1'000'000'007
//const int mod=1'000'000'007;
#define dim 100005
#define lim 1000000
#define BASE 31
#define NMAX 21'005
#define FOR(i,a,b) for(int i=(a); i<=(b); i++)
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> 
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define nr_biti __builtin_popcount
using namespace __gnu_pbds; 
using namespace std;

ifstream fin("heavypath.in");
ofstream fout("heavypath.out");

int t=1;
int n,q;
int v[dim];
vector<int> g[dim];
int par[dim];
int heavy[dim];
int sz[dim];
int h[dim];
int head[dim],pos[dim];
int inv[dim];
int auxx;

struct segtree 
{
    vector<int> aint;

    void init(int n)
    {
        aint=vector<int>(4*n+5,0);
    }

    void build(int nod,int st,int dr)
    {
        if(st==dr)
        {
            aint[nod]=v[inv[st]];
            return;
        }

        int mij=(st+dr)/2;
        build(2*nod,st,mij);
        build(2*nod+1,mij+1,dr);
        aint[nod]=max(aint[2*nod],aint[2*nod+1]);
    }

    void update(int nod,int st,int dr,int pos,int val)
    {
        if(st==dr)
        {
            aint[nod]=val;
            return;
        }

        int mij=(st+dr)/2;
        if(pos<=mij)
            update(2*nod,st,mij,pos,val);
        else 
            update(2*nod+1,mij+1,dr,pos,val);

        aint[nod]=max(aint[2*nod],aint[2*nod+1]);
    }

    int query(int nod,int st,int dr,int qst,int qdr)
    {
        if(st>dr)
            return 0;
        if(st>qdr || dr<qst)
            return 0;

        if(st>=qst && dr<=qdr)
            return aint[nod];

        int mij=(st+dr)/2;
        return max(query(2*nod,st,mij,qst,qdr),query(2*nod+1,mij+1,dr,qst,qdr));
    }
}a;

void dfs(int nod,int daddy=0)
{
    h[nod]=1+h[daddy];
    par[nod]=daddy;
    sz[nod]=1;
    int mx=-1;

    for(auto it:g[nod])
    {
        if(it==par[nod])
            continue;

        dfs(it,nod);
        sz[nod]+=sz[it];

        if(sz[it]>mx)
        {
            mx=sz[it];
            heavy[nod]=it;
        }
    }
}

void desc(int nod,int capat)
{
    head[nod]=capat;
    pos[nod]=++auxx;
    inv[auxx]=nod;

    if(heavy[nod])
        desc(heavy[nod],capat);

    for(auto it:g[nod])
    {
        if(it==par[nod])
            continue;

        if(it==heavy[nod])
            continue;

        desc(it,it);
    }
}

int query(int x,int y)
{
    int ans=0;
    for(; head[x]!=head[y]; y=par[head[y]])
    {
        if(h[head[x]]>h[head[y]])
            swap(x,y);

        ans=max(ans,a.query(1,1,n,pos[head[y]],pos[y]));
    }

    if(h[x]>h[y])
        swap(x,y);

    ans=max(ans,a.query(1,1,n,pos[x],pos[y]));
    return ans;
}

void solve()
{
    fin >> n >> q;
    for(int i=1; i<=n; i++)
        fin >> v[i];

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

    dfs(1);
    desc(1,1);
    a.init(n);
    a.build(1,1,n);

    while(q--)
    {
        int tip,x,y;
        fin >> tip >> x >> y;

        if(!tip)
        {
            v[x]=y;
            a.update(1,1,n,pos[x],v[x]);
        }
        else 
        {
            fout << query(x,y) << "\n";
        }
    }
}   

int main()
{
    ios_base::sync_with_stdio(false);
    fin.tie(nullptr);
    fout.tie(nullptr);

    //fin >> t;
    while(t--)
        solve();

    return 0;
}