Advertisement
fooker

path queries 2

Feb 11th, 2024
958
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.81 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4.  
  5. const ll nmax = 1e9+7;
  6. const ll nmax2 = 998244353;
  7.  
  8. int main(){
  9.     std::ios_base::sync_with_stdio(false);
  10.     std::cin.tie(0);
  11.     std::cout.tie(0);
  12.  
  13.     ll n, q;
  14.     std::cin >> n >> q;
  15.  
  16.     std::vector<ll> a(n + 1);
  17.     for (ll i = 1; i <= n; i++) std::cin >> a[i];
  18.  
  19.     std::vector<ll> adj[n + 1];
  20.     for (ll i = 1, x, y; i < n; i++){
  21.         std::cin >> x >> y;
  22.  
  23.         adj[x].push_back(y);
  24.         adj[y].push_back(x);
  25.     }
  26.  
  27.     std::vector<ll> sz(n + 1), depth(n + 1), par(n + 1);
  28.     std::function<ll(ll, ll)> dfs = [&] (ll u, ll p){
  29.         par[u] = p;
  30.         sz[u] = 1;
  31.         for (auto v: adj[u]){
  32.             if (v == p) continue;
  33.             depth[v] = depth[u] + 1;
  34.             sz[v] += dfs(v, u);
  35.         }  
  36.         return sz[u];
  37.     };
  38.     auto waste = dfs(1, 1);
  39.  
  40.     ll cnt = 1;
  41.     std::vector<ll> id(n + 1), tp(n + 1), st(2 * n + 5);
  42.  
  43.     std::function<void(ll, ll)> update = [&] (ll ind, ll val){
  44.         for (st[ind += n - 1] = val; ind > 1; ind >>= 1) st[ind >> 1] = std::max(st[ind], st[ind ^ 1]);
  45.     };
  46.  
  47.     std::function<void(ll, ll, ll)> dfs_hld = [&] (ll u, ll p, ll top){
  48.         id[u] = cnt++;
  49.         tp[u] = top;
  50.  
  51.         update(id[u], a[u]);
  52.         ll heavy_child = -1, heavy_size = -1;
  53.         for (auto v : adj[u]){
  54.             if (v == p) continue;
  55.             if (sz[v] > heavy_size){
  56.                 heavy_size = sz[v];
  57.                 heavy_child = v;
  58.             }
  59.         }
  60.  
  61.         if (heavy_size == -1) return;
  62.         dfs_hld(heavy_child, u, tp[u]);
  63.  
  64.         for (auto v: adj[u]){
  65.             if (v == p or v == heavy_child) continue;
  66.             dfs_hld(v, u, v);
  67.         }
  68.     };  
  69.     dfs_hld(1, 1, 1);
  70.  
  71.     std::function<ll(ll, ll)> query = [&] (ll low, ll high){
  72.         ll ra = 0, rb = 0;
  73.         for (low += n - 1, high += n - 1; low < high; low >>= 1, high >>= 1){
  74.             if (low & 1) ra = std::max(ra, st[low++]);
  75.             if (high & 1) rb = std::max(rb, st[--high]);
  76.         }
  77.         return std::max(low, high);
  78.     };
  79.  
  80.     std::function<ll(ll, ll)> path = [&] (ll x, ll y){
  81.         ll res = 0;
  82.         while (tp[x] != tp[y]){
  83.             if (depth[tp[x]] < depth[tp[y]]) std::swap(x, y);
  84.             res = std::max(res, query(id[tp[x]], id[x]));
  85.             x = par[tp[x]];
  86.         }
  87.  
  88.         if (depth[x] > depth[y]) std::swap(x, y);
  89.         res = std::max(res, query(id[x], id[y]));
  90.         return res;
  91.     };
  92.  
  93.     for (ll i = n - 1; i > 0; i--) st[i] = std::max(st[i << 1], st[i << 1 | 1]);
  94.  
  95.     for (ll i = 1, x, y, z; i <= q; i++){
  96.         std::cin >> x >> y >> z;
  97.         if (x == 1){
  98.             a[y] = z;
  99.             update(id[y], z);
  100.         } else if (x == 2){
  101.             std::cout << path(y, z) << '\n';
  102.         }
  103.     }
  104. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement