Cod sursa(job #3364154)

Utilizator Andrei_PanaAndrei Pana Andrei_Pana Data 31 august 2026 00:09:48
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.42 kb
#include <fstream>
#include <vector>
#include <climits>
using namespace std;

ifstream cin("heavypath.in");
ofstream cout("heavypath.out");

#define MAXN 100000

struct Node{
  int val;
  int tin,size,parent,depth;
  int heavy,head;
  vector<int> adj;
}nodes[MAXN+1];

int vals[MAXN+1];

struct SegmentTree{
  int arr[4*MAXN+1];
  int sz;

  void init(int n,int v[]){
    sz=1<<(32-__builtin_clz(n-1));

    for(int i=0;i<2*sz;i++){
      arr[i]=INT_MIN;
    }

    for(int i=1;i<=n;i++){
      arr[i+sz]=v[i];
    }

    for(int i=sz-1;i>=1;i--){
      arr[i]=max(arr[2*i],arr[2*i+1]);
    }
  }

  int getMax(int l,int r){
    int res=INT_MIN;
    l+=sz;
    r+=sz;
    while(l<=r){
      if(l&1){
        res=max(res,arr[l++]);
      }
      l>>=1;
      if(!(r&1)){
        res=max(res,arr[r--]);
      }
      r>>=1;
    }
    return res;
  }

  void pointUpdate(int pos,int val){
    pos+=sz;
    arr[pos]=val;
    pos>>=1;
    while(pos){
      arr[pos]=max(arr[2*pos],arr[2*pos+1]);
      pos>>=1;
    }
  }
}segtree;

void computeHeavy(int u,int p){
  nodes[u].size=1;
  nodes[u].parent=p;
  nodes[u].depth=nodes[p].depth+1;
  for(int v:nodes[u].adj){
    if(v!=p){
      computeHeavy(v,u);
      if(nodes[v].size>nodes[nodes[u].heavy].size){
        nodes[u].heavy=v;
      }
      nodes[u].size+=nodes[v].size;
    }
  }
}

void dfsFlatten(int u,int head){
  static int timer=0;
  nodes[u].tin=++timer;
  nodes[u].head=head;
  vals[nodes[u].tin]=nodes[u].val;

  if(nodes[u].heavy){
    dfsFlatten(nodes[u].heavy,head);
  }
  for(int v:nodes[u].adj){
    if(v!=nodes[u].parent&&v!=nodes[u].heavy){
      dfsFlatten(v,v);
    }
  }
}

int query(int u,int v){
  int ans=0;
  while(nodes[u].head!=nodes[v].head){
    if(nodes[nodes[v].head].depth>nodes[nodes[u].head].depth){
      swap(v,u);
    }
    ans=max(ans,segtree.getMax(nodes[nodes[u].head].tin,nodes[u].tin));
    u=nodes[nodes[u].head].parent;
  }

  if(nodes[u].depth>nodes[v].depth){
    swap(u,v);
  }
  ans=max(ans,segtree.getMax(nodes[u].tin,nodes[v].tin));

  return ans;
}

int main(){
  int n,m,i,u,v,type;

  cin>>n>>m;

  for(i=1;i<=n;i++){
    cin>>nodes[i].val;
  }

  for(i=0;i<n-1;i++){
    cin>>u>>v;
    nodes[u].adj.push_back(v);
    nodes[v].adj.push_back(u);
  }

  computeHeavy(1,0);
  dfsFlatten(1,1);

  segtree.init(n,vals);

  while(m--){
    cin>>type>>u>>v;

    if(type==0){
      segtree.pointUpdate(nodes[u].tin,v);
    }else{
      cout<<query(u,v)<<"\n";
    }
  }

  return 0;
}