Cod sursa(job #3303132)

Utilizator RaresHRares Hanganu RaresH Data 14 iulie 2025 10:08:13
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.48 kb
#include <stdio.h>
#include <vector>
#include <algorithm>

const int MAX_LEN = (1 << 17);

struct AINT {
  int n;
  int aint[2 * MAX_LEN];

  void init(int _n) {
    n = (1 << (32 - __builtin_clz(_n - 1)));
  }

  void update(int pos, int val) {
    pos += n;
    aint[pos] = val;
    for(pos /= 2; pos > 0; pos /= 2) {
      aint[pos] = std::max(aint[2 * pos], aint[2 * pos + 1]);
    }
  }

  int query(int l, int r) {
    l += n;
    r += n;
    int ret = -1;
    while(l <= r) {
      if(l % 2 == 1) {
        ret = std::max(ret, aint[l++]);
      }
      l /= 2;
      if(r % 2 == 0) {
        ret = std::max(ret, aint[r--]);
      }
      r /= 2;
    }
    return ret;
  }
};

const int MAX_N = 100'000;
int a[MAX_N], sz[MAX_N], tin[MAX_N], head[MAX_N], p[MAX_N];
std::vector<int> adj[MAX_N];
AINT aint;
FILE *fin, *fout;

void size_dfs(int u, int prev) {
  sz[u] = 1;
  p[u] = prev;
  for(int v : adj[u]) {
    if(v != prev) {
      size_dfs(v, u);
      sz[u] += sz[v];
    }
  }
}

int time;
void heavy_dfs(int u, int prev, int h) {
  tin[u] = time++;
  head[u] = h;
  int heavy = -1;
  for(int v : adj[u]) {
    if(v != prev && (heavy == -1 || sz[v] > sz[heavy])) {
      heavy = v;
    }
  }
  if(heavy > -1) {
    heavy_dfs(heavy, u, h);
  }
  for(int v : adj[u]) {
    if(v != prev && v != heavy) {
      heavy_dfs(v, u, v);
    }
  }
}

int hld_query(int u, int v) {
  int ret = -1;
  while(head[u] != head[v]) {
    if(tin[u] < tin[v]) {
      std::swap(u, v);
    }
    ret = std::max(ret, aint.query(tin[head[u]], tin[u]));
    u = p[head[u]];
  }
  if(tin[u] < tin[v]) {
    std::swap(u, v);
  }
  ret = std::max(ret, aint.query(tin[v], tin[u]));
  return ret;
}

int main() {
  fin = fopen("heavypath.in", "r");
  fout = fopen("heavypath.out", "w");

  int n, q;
  fscanf(fin, "%d%d", &n, &q);
  for(int i = 0; i < n; i++) {
    fscanf(fin, "%d", &a[i]);
  }
  for(int i = 0; i < n - 1; i++) {
    int u, v;
    fscanf(fin, "%d%d", &u, &v);
    u--; v--;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }

  size_dfs(0, -1);
  time = 0;
  heavy_dfs(0, -1, 0);

  aint.init(n);
  for(int i = 0; i < n; i++) {
    aint.update(tin[i], a[i]);
  }

  for(int i = 0; i < q; i++) {
    int t;
    fscanf(fin, "%d", &t);
    if(t == 0) {
      int nd, val;
      fscanf(fin, "%d%d", &nd, &val);
      nd--;
      aint.update(tin[nd], val);
    } else {
      int u, v;
      fscanf(fin, "%d%d", &u, &v);
      u--; v--;
      fprintf(fout, "%d\n", hld_query(u, v));
    }
  }

  fclose(fin);
  fclose(fout);

  return 0;
}