Advertisement
Guest User

Untitled

a guest
Apr 11th, 2020
272
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.31 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5.  
  6. struct LinkCut {
  7.   struct Node {
  8.     int p = 0, c[2] = {0, 0}, pp = 0;
  9.     bool flip = 0;
  10.     int val = 0, dp = 0;
  11.   };
  12.   vector<Node> T;
  13.  
  14.   LinkCut(int n) : T(n + 1) {}
  15.  
  16.   // SPLAY TREE OPERATIONS START
  17.  
  18.   int dir(int x, int y) { return T[x].c[1] == y; }
  19.  
  20.   void set(int x, int d, int y) {
  21.     if (x) T[x].c[d] = y, pull(x);
  22.     if (y) T[y].p = x;
  23.   }
  24.  
  25.   void pull(int x) {
  26.     if (!x) return;
  27.     int &l = T[x].c[0], &r = T[x].c[1];
  28.     T[x].dp = max({T[x].val, T[l].dp, T[r].dp});
  29.   }
  30.  
  31.   void push(int x) {
  32.     if (!x || !T[x].flip) return;
  33.     int &l = T[x].c[0], &r = T[x].c[1];
  34.     swap(l, r); T[l].flip ^= 1; T[r].flip ^= 1;
  35.     T[x].flip = 0;
  36.   }
  37.  
  38.   void rotate(int x, int d) {
  39.     int y = T[x].p, z = T[y].p, w = T[x].c[d];
  40.     swap(T[x].pp, T[y].pp);
  41.     set(y, !d, w);
  42.     set(x, d, y);
  43.     set(z, dir(z, y), x);
  44.   }
  45.  
  46.   void splay(int x) {
  47.     for (push(x); T[x].p;) {
  48.       int y = T[x].p, z = T[y].p;
  49.       push(z); push(y); push(x);
  50.       int dx = dir(y, x), dy = dir(z, y);
  51.       if (!z)
  52.         rotate(x, !dx);
  53.       else if (dx == dy)
  54.         rotate(y, !dx), rotate(x, !dx);
  55.       else
  56.         rotate(x, dy), rotate(x, dx);
  57.     }
  58.   }
  59.  
  60.   // SPLAY TREE OPERATIONS END
  61.  
  62.   void MakeRoot(int u) {
  63.     Access(u);
  64.     int l = T[u].c[0];
  65.     T[l].flip ^= 1;
  66.     swap(T[l].p, T[l].pp);
  67.     set(u, 0, 0);
  68.   }
  69.  
  70.   void Access(int _u) {
  71.     for (int v = 0, u = _u; u; u = T[v = u].pp) {
  72.       splay(u); splay(v);
  73.       int r = T[u].c[1];
  74.       T[v].pp = 0;
  75.       swap(T[r].p, T[r].pp);
  76.       set(u, 1, v);
  77.     }
  78.     splay(_u);
  79.   }
  80.  
  81.   void Link(int u, int v) {
  82.     assert(!Connected(u, v));
  83.     MakeRoot(v);
  84.     T[v].pp = u;
  85.   }
  86.  
  87.   void Cut(int u, int v) {
  88.     MakeRoot(u); Access(u); splay(v);
  89.     assert(T[v].pp == u);
  90.     T[v].pp = 0;
  91.   }
  92.  
  93.   bool Connected(int u, int v) {
  94.     if (u == v) return true;
  95.     MakeRoot(u); Access(v); splay(u);
  96.     return T[v].p == u || T[T[v].p].p == u;
  97.   }
  98.  
  99.   int GetPath(int u, int v) {
  100.     MakeRoot(u); Access(v); return v;
  101.   }
  102. };
  103.  
  104. void Test() {
  105.   int N = 100, Q = 100, V = 1000;
  106.   while (true) {
  107.     int n = rand() % N + 1;
  108.     int q = rand() % Q + 1;
  109.     int p1 = rand() % 100, p2 = rand() % 100, p3 = rand() % 100, p4 = rand() % 100, p5 = rand() % 100;
  110.  
  111.     vector<pair<int, int>> edges;
  112.     LinkCut lc(n);
  113.  
  114.     auto conn = [&](int a, int b) {
  115.       vector<int> dp(n + 1, -1);
  116.       dp[a] = lc.T[a].val;
  117.       for (int ch = 1; ch >= 0; ch--) {
  118.         for (auto p : edges) {
  119.           for (int it = 0; it < 2; ++it) {
  120.             if (dp[p.first] != -1 && dp[p.second] == -1) {
  121.               dp[p.second] = max(dp[p.first], lc.T[p.second].val);
  122.               ch = 1;
  123.             }
  124.             swap(p.first, p.second);
  125.           }
  126.         }
  127.       }
  128.       return dp[b];
  129.     };
  130.  
  131.  
  132.     auto sim_op = [&]() {
  133.       while (true) {
  134.         int t = rand() % (p1 + p2 + p3 + p4 + p5);
  135.  
  136.         if (t < p1) {
  137.           int a = rand() % n + 1, b = rand() % n + 1;
  138.           if (conn(a, b) == -1) {
  139.             edges.emplace_back(a, b);
  140.             lc.Link(a, b);
  141.             return;
  142.           }
  143.           continue;
  144.         }
  145.  
  146.         t -= p1;
  147.        
  148.         if (t < p2) {
  149.           if (edges.empty()) continue;
  150.           int pos = rand() % edges.size();
  151.           swap(edges[pos], edges.back());
  152.           // cerr << "CUT: " << edges.back().first << " " << edges.back().second << endl;
  153.           lc.Cut(edges.back().first, edges.back().second);
  154.           edges.pop_back();
  155.           return;
  156.         }
  157.  
  158.         t -= p2;
  159.        
  160.         if (t < p3) {
  161.           int node = rand() % n + 1;
  162.           lc.Access(node);
  163.           lc.T[node].val = rand() % V + 1;
  164.           lc.pull(node);
  165.           // cerr << "UPDATE: " << node << endl;
  166.           return;
  167.         }
  168.  
  169.         t -= p3;
  170.  
  171.         if (t < p4) {
  172.           int a = rand() % n + 1, b = rand() % n + 1;
  173.           int expected = conn(a, b);
  174.           if (expected != -1) {
  175.             // cerr << "QUERY: " << a << " " << b << endl;
  176.             int c = lc.GetPath(a, b);
  177.             int actual = lc.T[c].dp;
  178.             assert(expected == actual);
  179.             return;
  180.           }
  181.           continue;
  182.         }
  183.  
  184.         t -= p4;
  185.  
  186.         if (t < p5) {
  187.           int a = rand() % n + 1, b = rand() % n + 1;
  188.           // cerr << "CONNECTED: " << a << " " << b << endl;
  189.           int expected = (conn(a, b) != -1);
  190.           // cerr << "EXP: " << expected << endl;
  191.           int actual = lc.Connected(a, b);
  192.           assert(expected == actual);
  193.           return;
  194.         }
  195.  
  196.         assert(false);
  197.       }
  198.     };
  199.  
  200.     for (int i = 0; i < q; ++i) {
  201.       sim_op();
  202.     }
  203.  
  204.     cerr << "OK N = " << n << " Q = " << q << endl;
  205.   }
  206. }
  207.  
  208. int main() {
  209.   Test();
  210.   ifstream cin("heavypath.in");
  211.   ofstream cout("heavypath.out");
  212.  
  213.   int n, m; cin >> n >> m;
  214.   LinkCut lc(n);
  215.   for (int i = 1; i <= n; ++i) {
  216.     cin >> lc.T[i].val;
  217.   }
  218.  
  219.   for (int i = 1; i < n; ++i) {
  220.     int a, b; cin >> a >> b;
  221.     lc.Link(a, b);
  222.   }
  223.  
  224.   for (int i = 0; i < m; ++i) {
  225.     int t, a, b; cin >> t >> a >> b;
  226.     if (t == 0) {
  227.       lc.Access(a);
  228.       lc.T[a].val = b;
  229.       lc.pull(a);
  230.     } else {
  231.       a = lc.GetPath(a, b);
  232.       cout << lc.T[a].dp << '\n';
  233.     }
  234.   }
  235.   return 0;
  236. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement