Cod sursa(job #3304201)

Utilizator iordacheMatei Iordache iordache Data 21 iulie 2025 18:21:59
Problema Heavy Path Decomposition Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.92 kb
#include <bits/stdc++.h>
#define pb push_back
#define int long long
using namespace std;
const int N=1e5+5;
vector<int> g[N];
int val[N],sz[N],dep[N],par[N];
int paths=0;
int path[N],poz[N],len[N];
vector<vector<int>> v;
vector<int> dummy;
vector<vector<int>> aint;
void dfs(int node, int tata)
{
    par[node]=tata;
    if(tata!=0) dep[node]=dep[tata]+1;
    int mx=0,best=-1;
    sz[node]=1;
    for(auto x:g[node])
    {
        if(x==tata) continue;
        dfs(x,node);
        if(sz[x]>=mx) best=x;
        mx=max(mx,sz[x]);
        sz[node]+=sz[x];
    }
    if(best==-1)
    {
        path[node]=++paths;
        v.pb(dummy);
        v[path[node]].pb(node);
        return;
    }
    path[node]=path[best];
    v[path[node]].pb(node);
}
void build(int i, int node, int l, int r)
{
    if(l==r) {aint[i][node]=val[v[i][l]];return;}
    int mij=(l+r)/2;
    build(i,node*2,l,mij);
    build(i,node*2+1,mij+1,r);
    aint[i][node]=max(aint[i][node*2],aint[i][node*2+1]);
}
void update(int i, int node, int l, int r, int poz, int val)
{
    if(l==r) {aint[i][node]=val;return;}
    int mij=(l+r)/2;
    if(poz<=mij) update(i,node*2,l,mij,poz,val);
    else update(i,node*2+1,mij+1,r,poz,val);
    aint[i][node]=max(aint[i][node*2],aint[i][node*2+1]);
}
int query(int i, int node, int l, int r, int ql, int qr)
{
    if(ql<=l&&r<=qr) return aint[i][node];
    int mij=(l+r)/2;
    if(ql<=mij&&qr>=mij+1) return max(query(i,node*2,l,mij,ql,qr),query(i,node*2+1,mij+1,r,ql,qr));
    else if(ql<=mij) return query(i,node*2,l,mij,ql,qr);
    else return query(i,node*2+1,mij+1,r,ql,qr);
}
void decomp()
{
    aint.pb(dummy);
    for(int p=1;p<=paths;++p)
    {
        assert(p<v.size());
        len[p]=v[p].size();
        v[p].pb(-1);
        reverse(v[p].begin(),v[p].end());
        for(int i=1;i<=len[p];++i) poz[v[p][i]]=i;
        aint.pb(dummy);
        aint[p].resize(4*len[p]+5);
        build(p,1,1,len[p]);
    }
}
int getquery(int a, int b)
{
    int ans=-1e18;
    while(1)
    {
        if(dep[a]>dep[b]) swap(a,b);
        if(path[a]==path[b]) return max(ans,query(path[a],1,1,len[path[a]],poz[a],poz[b]));
        if(dep[v[path[a]][1]]>dep[v[path[b]][1]]) swap(a,b);
        ans=max(ans,query(path[b],1,1,len[path[b]],1,poz[b]));
        b=par[v[path[b]][1]];
    }
}
signed main()
{
    ifstream cin("heavypath.in");ofstream cout("heavypath.out");
    int n,q;
    cin>>n>>q;
    for(int i=1;i<=n;++i) cin>>val[i];
    for(int _=1;_<n;++_)
    {
        int uu,vv;cin>>uu>>vv;
        g[uu].pb(vv);
        g[vv].pb(uu);
    }
    v.pb(dummy);
    dfs(1,0);
    decomp();
    while(q--)
    {
        int op;cin>>op;
        if(op==0)
        {
            int x,y;cin>>x>>y;
            update(path[x],1,1,len[path[x]],poz[x],y);
        }
        else
        {
            int l,r;cin>>l>>r;
            cout<<getquery(l,r)<<'\n';
        }
    }
}