bingxuan9112

LCT-path-maximum

Aug 24th, 2020
2,103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.57 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define pb emplace_back
  3. #define debug(...) qqbx(#__VA_ARGS__, __VA_ARGS__)
  4. void qqbx(const char *s) {}
  5. template <typename H, typename ...T> void qqbx(const char *s, const H &h, T ...args) {
  6.     for(; *s && *s != ','; ++s) if(*s != ' ') std::cerr << *s;
  7.     std::cerr << " = " << h << (sizeof...(T) ? ", " : "\n");
  8.     if (sizeof...(T)) qqbx(++s, args...);
  9. }
  10.  
  11. using namespace std;
  12. typedef int64_t ll;
  13. const int N = 200025, MOD = 1000000007;
  14.  
  15. struct LCT {
  16.     struct node {
  17.         int pa, ch[2];
  18.         int mx, v;
  19.         node(int pa = 0, int v = 0) : pa(pa), v(v), mx(v) { ch[0]=ch[1]=0; }
  20.     } T[N];
  21.     int dir(int x) {
  22.         return T[T[x].pa].ch[1] == x;
  23.     }
  24.     int isroot(int x) {
  25.         return T[T[x].pa].ch[dir(x)] != x;
  26.     }
  27.     void pull(int x) {
  28.         T[x].mx = max({ T[x].v, T[T[x].ch[0]].mx, T[T[x].ch[1]].mx });
  29.     }
  30.     void rot(int x) {
  31.         int y = T[x].pa, z = T[y].pa, d = dir(x);
  32.         T[x].pa = z;
  33.         if(!isroot(y)) T[z].ch[dir(y)] = x;
  34.         T[T[x].ch[!d]].pa = y;
  35.         T[y].ch[d] = T[x].ch[!d];
  36.         T[y].pa = x;
  37.         T[x].ch[!d] = y;
  38.         pull(y), pull(x);
  39.     }
  40.     void splay(int x) {
  41.         while(!isroot(x)) {
  42.             int y = T[x].pa;
  43.             if(!isroot(y))
  44.                 rot(dir(x) ^ dir(y) ? x : y);
  45.             rot(x);
  46.         }
  47.     }
  48.     int access(int x) {
  49.         int last = 0;
  50.         while(x) {
  51.             splay(x);
  52.             T[x].ch[1] = last;
  53.             pull(x);
  54.             last = x;
  55.             x = T[x].pa;
  56.         }
  57.         return last;
  58.     }
  59.     int query(int a, int b) {
  60.         access(a);
  61.         int LCA = access(b);
  62.         splay(a);
  63.         if(a == LCA) return max( T[LCA].v, T[T[LCA].ch[1]].mx );
  64.         return max({ T[a].mx, T[LCA].v, T[T[LCA].ch[1]].mx });
  65.     }
  66.     void update(int a, int d) {
  67.         splay(a);
  68.         T[a].v = d;
  69.         pull(a);
  70.     }
  71. } lct;
  72. vector<int> g[N];
  73. int w[N];
  74. void dfs(int i, int p) {
  75.     lct.T[i] = LCT::node(p, w[i]);
  76.     for(int j: g[i]) {
  77.         if(j == p) continue;
  78.         dfs(j, i);
  79.     }
  80. }
  81. signed main() {
  82.     ios_base::sync_with_stdio(0), cin.tie(0);
  83.     int n, q;
  84.     cin >> n >> q;
  85.     for(int i = 1; i <= n; i++) cin >> w[i];
  86.     for(int i = 1; i < n; i++) {
  87.         int a, b;
  88.         cin >> a >> b;
  89.         g[a].pb(b), g[b].pb(a);
  90.     }
  91.     dfs(1, 0);
  92.     while(q--) {
  93.         int com, a, b;
  94.         cin >> com >> a >> b;
  95.         if(com == 1) {
  96.             cout << lct.query(a, b) << '\n';
  97.         } else {
  98.             lct.update(a, b);
  99.         }
  100.     }
  101. }
  102.  
Advertisement
Add Comment
Please, Sign In to add comment