Cod sursa(job #3287934)

Utilizator Horia_haivasHaivas Horia Horia_haivas Data 19 martie 2025 21:35:16
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.5 kb
#include<bits/stdc++.h>
#define debug(x) cerr << #x << " " << x << "\n"
#define debugs(x) cerr << #x << " " << x << " "
#pragma GCC optimize("Ofast")
#define int long long

using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int range_rng(int l, int r)
{
    return uniform_int_distribution<int>(l,r)(rng);
}

int v[100005];
int stamp[100005];
int cv[100005];
vector<int> nodes[100005];
int h[100005];
int p[100005];
int heavychild[100005];
int sz[100005];
int pathend[100005];
int timer;

class AINT
{
public:
    int aint[400005];
    void build(int l, int r, int val)
    {
        if (l==r)
        {
            aint[val]=v[l];
            return;
        }
        int mid;
        mid=(l+r)/2;
        build(l,mid,val*2);
        build(mid+1,r,val*2+1);
        aint[val]=max(aint[val*2],aint[val*2+1]);
    }
    void update(int l, int r, int val, int poz, int x)
    {
        if (l==r)
        {
            v[l]=x;
            aint[val]=v[l];
            return;
        }
        int mid;
        mid=(l+r)/2;
        if (poz<=mid)
            update(l,mid,val*2,poz,x);
        else
            update(mid+1,r,val*2+1,poz,x);
        aint[val]=max(aint[val*2],aint[val*2+1]);
    }

    int query(int l, int r, int val, int qa, int qb)
    {
        if (qa<=l && r<=qb)
        {
            return aint[val];
        }
        int mid,ans;
        ans=-1;
        mid=(l+r)/2;
        if (qa<=mid)
            ans=max(ans,query(l,mid,val*2,qa,qb));
        if (qb>mid)
            ans=max(ans,query(mid+1,r,val*2+1,qa,qb));
        return ans;
    }

    void update(int node, int val)
    {
        update(1,timer,1,stamp[node],val);
    }


    int query(int u, int v)
    {
        int ans;
        ans=-1;
        while (pathend[u]!=pathend[v])
        {
            if (h[pathend[u]]<h[pathend[v]])
                swap(u,v);
            ans=max(ans,query(1,timer,1,stamp[pathend[u]],stamp[u]));
            u=p[pathend[u]];
        }
        if (stamp[u]>stamp[v])
            swap(u,v);
        ans=max(ans,query(1,timer,1,stamp[u],stamp[v]));
        return ans;
    }

} aint;

void dfs(int node, int parent)
{
    int mx;
    mx=0;
    p[node]=parent;
    sz[node]=1;
    for (auto x : nodes[node])
    {
        if (x!=parent)
        {
            h[x]=h[node]+1;
            dfs(x,node);
            sz[node]+=sz[x];
            if (sz[x]>sz[mx])
                mx=x;
        }
    }
    heavychild[node]=mx;
}

void heavyfirst(int node, int parent, int capat)
{
    stamp[node]=++timer;
    v[timer]=cv[node];
    pathend[node]=capat;
    if (heavychild[node]==0)
        return;
    heavyfirst(heavychild[node],node,capat);
    for (auto x : nodes[node])
    {
        if (x!=parent && x!=heavychild[node])
        {
            heavyfirst(x,node,x);
        }
    }
}

signed main()
{
    ifstream fin("heavypath.in");
    ofstream fout("heavypath.out");
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n,m,i,j,x,y,type;
    fin >> n >> m;
    for (i=1; i<=n; i++)
    {
        fin >> cv[i];
    }
    for (i=1; i<=n-1; i++)
    {
        fin >> x >> y;
        nodes[x].push_back(y);
        nodes[y].push_back(x);
    }
    h[1]=1;
    dfs(1,0);
    timer=0;
    heavyfirst(1,0,1);
    aint.build(1,timer,1);
    for (i=1; i<=m; i++)
    {
        fin >> type;
        if (type==0)
        {
            fin >> x >> y;
            aint.update(x,y);
        }
        else
        {
            fin >> x >> y;
            fout << aint.query(x,y) << "\n";
        }
    }
    return 0;
}