Cod sursa(job #3293799)

Utilizator andreic06Andrei Calota andreic06 Data 12 aprilie 2025 16:59:03
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.98 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");

const int N_MAX = 1e5;
const int Q_MAX = 1e5;


struct defST {
    int DS[1 + 4 * N_MAX];
    void update (int node, int left, int right, int pos, int x) {
       if (left == right) DS[node] = x;
       else {
         int mid = left + (right - left) / 2;
         if (pos <= mid) update (2 * node, left, mid, pos, x);
         else update (2 * node + 1, mid + 1, right, pos, x);
         DS[node] = max (DS[2 * node], DS[2 * node + 1]);
       }
    }
    int query (int node, int left, int right, int qleft, int qright) {
       if (qleft <= left && right <= qright) return DS[node];
       int mid = left + (right - left) / 2;

       int ret = 0;
       if (qleft <= mid) ret = max (ret, query (2 * node, left, mid, qleft, qright));
       if (mid + 1 <= qright) ret = max (ret, query (2 * node + 1, mid + 1, right, qleft, qright));
       return ret;
    }
} ST;

int N, Q; int values[1 + N_MAX];
vector<int> tree[1 + N_MAX];
void readInput (void) {
   fin >> N >> Q;
   for (int node = 1; node <= N; node ++) fin >> values[node];
   for (int i = 1; i < N; i ++) {
      int u, v; fin >> u >> v;
      tree[u].push_back (v);
      tree[v].push_back (u);
   }
}

struct defNode {
   int p, siz, depth;
   int pos, head;
} infos[1 + N_MAX];

void dfs (int root, int p) {
   infos[root].p = p;
   infos[root].depth = infos[p].depth + 1;
   infos[root].siz = 1;
   for (int node : tree[root]) {
      if (node == p) continue;
      dfs (node, root);
      infos[root].siz += infos[node].siz;
   }
}

int T = 0;
void dfsHeavy (int root, int p, int head) {
   infos[root].pos = ++ T;
   infos[root].head = head;

   int hc = 0;
   for (int node : tree[root]) {
      if (node == p) continue;
      if (infos[hc].siz < infos[node].siz)
        hc = node;
   }
   if (hc > 0) dfsHeavy (hc, root, head);
   for (int node : tree[root]) {
      if (node == p || node == hc) continue;
      dfsHeavy (node, root, node);
   }
}


void update (int node, int new_value) {
   ST.update (1, 1, N, infos[node].pos, new_value);
}
int query (int u, int v) {
   int ret = 0;
   while (infos[u].head != infos[v].head) {
      int hu = infos[u].head, hv = infos[v].head;
      if (infos[hu].depth > infos[hv].depth) {
        swap (u, v);
        swap (hu, hv);
      }
      ret = max (ret, ST.query (1, 1, N, infos[hv].pos, infos[v].pos));
      v = infos[hv].p;
   }
   if (infos[u].depth > infos[v].depth) swap (u, v);
   ret = max (ret, ST.query (1, 1, N, infos[u].pos, infos[v].pos));
   return ret;
}

int main () {

   readInput ();
   dfs (1, 0);
   dfsHeavy (1, 0, 1);
   for (int node = 1; node <= N; node ++) ST.update (1, 1, N, infos[node].pos, values[node]);

   for (int i = 1; i <= Q; i ++) {
      int t, x, y; fin >> t >> x >> y;
      if (t == 0) update (x, y);
      else fout << query (x, y) << "\n";
   }
   return 0;
}