Cod sursa(job #2981737)

Utilizator Stormtrooper-007Vartic Rihard Stormtrooper-007 Data 18 februarie 2023 16:27:32
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.75 kb
#include <bits/stdc++.h>

using namespace std;
int n,q;
int inf=1e9;
vector<int>v;
vector<int>kid_sz;
vector<int>send;
vector<int>I;
vector<int>tin;
vector<int>tout;
vector<vector<int>>pre;
int in=1,taime=0;
vector<vector<int>>adj;
//LCA
void info_dfs(int a,int prev)
{
    pre[a][0]=prev;
    for(int i=1;i<30;i++)
    {
        int b=pre[a][i-1];
        if(b==-1)
        break;
        pre[a][i]=pre[b][i-1];
    }
    tin[a]=++taime;
    for(auto x:adj[a])
    {
        if(x!=prev)
        {
            info_dfs(x,a);
        }
    }
    tout[a]=taime;
}
bool first_is_upper(int a,int b)
{
    if(tin[a]<=tin[b] && tout[a]>=tout[b])
    return 1;
    else
    return 0;
}
int LCA(int a,int b)
{
    if(first_is_upper(a,b))
    {
        return a;
    }
    else if(first_is_upper(b,a))
    {
        return b;
    }
    for(int i=29;i>=0;i--)
    {
        int c=pre[b][i];
        if(c!=-1 && !first_is_upper(c,a))
        {
            b=c;
        }
    }
    return pre[b][0];
}
void deep_dfs(int a,int prev)
{
    for(auto x:adj[a])
    {
        if(x!=prev)
        {
            deep_dfs(x,a);
            kid_sz[a]+=kid_sz[x];
        }
    }
    kid_sz[a]++;
    return;
}
void path_dfs(int a,int prev)
{
    I[a]=in++;
    if(send[a]==0)
    send[a]=a;
    vector<pair<int,int>>order;
    for(auto x:adj[a])
    {
        if(x!=prev)
        {
            order.push_back({kid_sz[x],x});
        }
    }
    sort(order.rbegin(),order.rend());
    for(int i=0;i<order.size();i++)
    {
        if(i==0)
        {
            send[order[i].second]=send[a];
        }
        path_dfs(order[i].second,a);
    }
}
struct segtree
{
    int n = 1;
  vector<int> T;
  segtree(vector<int>& A) {
    while (n < A.size()) n *= 2;
    T.assign(2 * n, -inf);
    for (int i = 0; i < A.size(); ++i) {
      T[i + n] = A[i];
    }
    for (int i = n - 1; i >= 1; --i) {
      T[i] = max(T[i * 2], T[i * 2 + 1]);
    }
  }
  int Get(int l, int r) {
    int ans = -inf;
    for (l += n, r += n; l <= r; l /= 2, r /= 2) {
      if (l % 2 == 1) ans = max(ans, T[l++]);
      if (r % 2 == 0) ans = max(ans, T[r--]);
    }
    return ans;
  }

  void Set(int i, int v) {
    i += n;
    T[i] = v;
    i /= 2;
    while (i >= 1) {
      T[i] = max(T[i * 2], T[i * 2 + 1]);
      i /= 2;
    }

  }
};
int numdfs(int a,int b,segtree &h)
{int ma=-1e9;
    if(!first_is_upper(send[a],b))
    {
        ma=max(ma,h.Get(I[send[a]],I[a]));
        ma=max(numdfs(pre[send[a]][0],b,h),ma);
    }
    else
    {
        ma=max(ma,h.Get(I[b],I[a]));
    }
    return ma;
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie();
    cout.tie();
  //  ifstream cin("heavypath.in");
   // ofstream cout("heavypath.out");
    cin>>n>>q;
    v.assign(n+1,0);
    kid_sz.assign(n+1,0);
    tin.assign(n+1,0);
    tout.assign(n+1,0);
    I.assign(n+1,0);
    send.assign(n+1,0);
    adj.assign(n+1,vector<int>(0));
    pre.assign(n+1,vector<int>(30,-1));
    for(int i=1;i<=n;i++)
    {
        cin>>v[i];
    }
    for(int i=0;i<n-1;i++)
    {
        int a,b;
        cin>>a>>b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    info_dfs(1,-1);
    deep_dfs(1,-1);
    path_dfs(1,-1);
    vector<int>B(n+1);
    for(int i=1;i<=n;i++)
    {
        B[I[i]]=v[i];
    }
    segtree h(B);
    while(q--)
    {
        int t;
        cin>>t;
        if(t==0)
        {
            int s,x;
            cin>>s>>x;
            h.Set(I[s],x);
        }
        else
        {
            int l,r;
            cin>>l>>r;
            int c=LCA(l,r);
            cout<<(max(numdfs(l,c,h),numdfs(r,c,h)))<<"\n";
        }
    }
    return 0;
}