Mlxa

TEAMBOOK HLD + быстрый ввод

Nov 1st, 2019
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.55 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define long long long
  3. #define all(x) x.begin(), x.end()
  4. using namespace std;
  5.  
  6. const int BUFFER_SIZE = 1 << 16;
  7. char inBuffer[BUFFER_SIZE], outBuffer[BUFFER_SIZE];
  8. int inLen = 0, inPtr = 0, outPtr = 0;
  9. __attribute__((destructor))
  10. void flushOut() {
  11.     fwrite(outBuffer, 1, outPtr, stdout);
  12.     outPtr = 0;
  13. }
  14. bool canRead() {
  15.     if (inPtr == inLen) {
  16.         inLen = fread(inBuffer, 1, BUFFER_SIZE, stdin);
  17.         inPtr = 0;
  18.     }
  19.     return inPtr < inLen;
  20. }
  21. char peekChar() {
  22.     if (!canRead()) {
  23.         return 0;
  24.     }
  25.     return inBuffer[inPtr++];
  26. }
  27. char getChar() {
  28.     if (!canRead()) {
  29.         return 0;
  30.     }  
  31.     return inBuffer[inPtr++];
  32. }
  33. template<class T>
  34. T read();
  35. template<class T>
  36. void write(T);
  37. template<>
  38. char read() {
  39.     char c = getChar();
  40.     while (c == ' ' || c == '\n') {
  41.         c = getChar();
  42.     }
  43.     return c;
  44. }
  45. template<>
  46. int read() {
  47.     int sign = 1, x = 0;
  48.     char c   = read<char>();
  49.     if (c == '-') {
  50.         sign = -1; c = getChar();
  51.     }
  52.     while ('0' <= c && c <= '9') {
  53.         x = 10 * x + c - '0';
  54.         c = getChar();
  55.     }
  56.     return x * sign;
  57. }
  58. void write(char c) {
  59.     if (outPtr == BUFFER_SIZE) {
  60.         flushOut();
  61.     }
  62.     outBuffer[outPtr++] = c;
  63. }
  64. void write(int x) {
  65.     static char s[30];
  66.     int n = 0;
  67.     if (x < 0) {
  68.         write('-');
  69.         x = -x;
  70.     }
  71.     while (!n || x) {
  72.         s[n++] = x % 10 + '0';
  73.         x /= 10;
  74.     }
  75.     while (n--) {
  76.         write(s[n]);
  77.     }
  78. }
  79. void write(long x) {
  80.     static char s[30];
  81.     int n = 0;
  82.     if (x < 0) {
  83.         write('-');
  84.         x = -x;
  85.     }
  86.     while (!n || x) {
  87.         s[n++] = x % 10 + '0';
  88.         x /= 10;
  89.     }
  90.     while (n--) {
  91.         write(s[n]);
  92.     }
  93. }
  94. void write(const char *i) {
  95.     for (; *i; ++i) {
  96.         write(*i);
  97.     }
  98. }
  99. void write() {}
  100. template<class A, class... B>
  101. void write(A a, B... b) {
  102.     write(a);
  103.     write(b...);
  104. }
  105.  
  106. const int N = 3e5;
  107. vector<int> g[N];
  108. int n, parent[N], sz[N], initH[N], tin[N], tout[N], start[N], timer = 0;
  109.  
  110. bool isAnc(int v, int u) {
  111.     return tin[v] <= tin[u] && tout[u] <= tout[v];
  112. }
  113.  
  114. void countSize(int v, int p) {
  115.     parent[v] = p;
  116.     sz[v] = 1;
  117.     for (int u : g[v]) {
  118.         if (u == p) {
  119.             continue;
  120.         }
  121.         countSize(u, v);
  122.         sz[v] += sz[u];
  123.     }
  124. }
  125.  
  126. void precalc(int v, int st, int p) {
  127.     start[v] = st;
  128.     tin[v] = timer++;
  129.     auto it = find(all(g[v]), p);
  130.     if (it != g[v].end()) {
  131.         g[v].erase(it);
  132.     }
  133.     if (g[v].empty()) {
  134.         tout[v] = timer;
  135.         return;
  136.     }
  137.     for (int &u : g[v]) {
  138.         if (sz[u] > sz[g[v].front()]) {
  139.             swap(u, g[v].front());
  140.         }
  141.     }
  142.     precalc(g[v][0], st, v);
  143.     for (int i = 1; i < (int)g[v].size(); ++i) {
  144.         int u = g[v][i];
  145.         precalc(u, u, v);
  146.     }
  147.     tout[v] = timer;
  148. }
  149.  
  150. int hldTime[N], prefixTime[N];
  151. int st[2 * N];
  152.  
  153. void treeUpdate(int i, int j) {
  154.     st[i += N] = j;
  155.     for (i >>= 1; i > 0; i >>= 1) {
  156.         st[i] = max(st[2 * i], st[2 * i + 1]);
  157.     }
  158. }
  159.  
  160. void update(int i, int j) {
  161.     ++timer;
  162.     hldTime[start[i]] = timer;
  163.     treeUpdate(tin[i], j);
  164. }
  165.  
  166. int treeMax(int l, int r) {
  167.     int res = 0;
  168.     for (l += N, r += N; l <= r; l >>= 1, r >>= 1) {
  169.         if (l & 1) {
  170.             res = max(res, st[l++]);
  171.         }
  172.         if (!(r & 1)) {
  173.             res = max(res, st[r--]);
  174.         }
  175.     }
  176.     return res;
  177. }
  178.  
  179. int _cnt = 0;
  180. int _sum = 0;
  181. int _helped = 0;
  182. int _full   = 0;
  183.  
  184. int saved[N];
  185.  
  186. int prefixQuery(int i) {
  187.     //cerr << "prefix " << i + 1 << endl;
  188.     //if (prefixTime[i] < hldTime[start[i]]) {
  189.         prefixTime[i] = timer;
  190.         saved[i] = treeMax(tin[start[i]], tin[i]);
  191.     //} else {
  192.     //  ++_helped;
  193.     //}
  194.     //++_full;
  195.     return saved[i];
  196. }
  197.  
  198. int query(int v, int u) {
  199.     ++_cnt;
  200.     int res = 0;
  201.     while (!isAnc(start[v], u)) {
  202.         ++_sum;
  203.         res = max(res, prefixQuery(v));
  204.         v = parent[start[v]];
  205.     }
  206.     while (!isAnc(start[u], v)) {
  207.         ++_sum;
  208.         res = max(res, prefixQuery(u));
  209.         u = parent[start[u]];
  210.     }
  211.     assert(start[v] == start[u]);
  212.     int l = tin[v];
  213.     int r = tin[u];
  214.     if (l > r) {
  215.         swap(l, r);
  216.     }
  217.     ++_sum;
  218.     return max(res, treeMax(l, r));
  219. }
  220.  
  221. int main() {
  222. #ifdef LC
  223.     assert(freopen("input.txt", "r", stdin));
  224. #endif
  225.     ios::sync_with_stdio(0);
  226.     cin.tie(0);
  227.     n = read<int>();
  228.     for (int i = 0; i < n; ++i) {
  229.         initH[i] = read<int>();
  230.     }
  231.     for (int u, v, i = 0; i < n - 1; ++i) {
  232.         v = read<int>() - 1;
  233.         u = read<int>() - 1;
  234.         g[v].push_back(u);
  235.         g[u].push_back(v);
  236.     }
  237.     fill_n(prefixTime, N, -1);
  238.     countSize(0, 0);
  239.     precalc(0, 0, 0);
  240.     for (int i = 0; i < n; ++i) {
  241.         st[N + tin[i]] = initH[i];
  242.     }
  243.     for (int i = N - 1; i > 0; --i) {
  244.         st[i] = max(st[2 * i], st[2 * i + 1]);
  245.     }
  246.     int q = read<int>();
  247.     while (q--) {
  248.         char tp = read<char>();
  249.         if (tp == '!') {
  250.             int i = read<int>(), j = read<int>();
  251.             update(i - 1, j);
  252.         } else {
  253.             int i = read<int>(), j = read<int>();
  254.             write(query(i - 1, j - 1), '\n');
  255.         }
  256.     }
  257.     return 0;
  258. }
Add Comment
Please, Sign In to add comment