Advertisement
double_trouble

heavy-light decomposition

Sep 29th, 2016
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.73 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <iostream>
  3. #include <cstdio>
  4. #include <vector>
  5. #include <cmath>
  6. #include <string>
  7. #include <algorithm>
  8. #include <string>
  9. #include <deque>
  10. #include <iomanip>
  11. #include <cstddef>
  12. #include <queue>
  13.  
  14.  
  15. using namespace std;
  16.  
  17. vector<vector<int> > g, chain;
  18. int num[100100], used[100100], fin[100100], key[100100], unkey[100100], par[100100], val[100100];
  19. int tree[1000100];
  20. vector<vector<long long> > t;
  21. pair<int, int> pos[100100];
  22. vector<int> ord;
  23.  
  24. void dfsCount(int v)
  25. {
  26.     used[v] = 1;
  27.     ++num[v];
  28.  
  29.     for (int i = 0; i < g[v].size(); i++) {
  30.         int to = g[v][i];
  31.         if (!used[to])
  32.         {
  33.             dfsCount(to);
  34.             num[v] += num[to];
  35.             par[to] = v;
  36.         }
  37.     }
  38. }
  39.  
  40. void dfsChain(int v)
  41. {
  42.     used[v] = 1;
  43.     bool f = 1;
  44.  
  45.     for (int i = 0; i < g[v].size(); i++)
  46.     {
  47.         int to = g[v][i];
  48.         if (!used[to])
  49.         {
  50.             dfsChain(to);
  51.             if (2 * num[to] >= num[v])
  52.             {
  53.                 pos[v] = make_pair(pos[to].first, chain[pos[to].first].size());
  54.                 chain[pos[v].first].push_back(v);
  55.                 f = 0;
  56.             }
  57.         }
  58.     }
  59.  
  60.     if (f)
  61.     {
  62.         pos[v] = make_pair(v, 0);
  63.         chain[v].push_back(v);
  64.     }
  65. }
  66.  
  67. int timer = 0;
  68.  
  69. void dfsLca(int v)
  70. {
  71.     used[v] = 1;
  72.     key[v] = timer++;
  73.     unkey[key[v]] = v;
  74.     if (fin[v] == -1)
  75.         fin[v] = ord.size();
  76.     ord.push_back(key[v]);
  77.  
  78.     for (int i = 0; i < g[v].size(); i++)
  79.     {
  80.         int to = g[v][i];
  81.         if (!used[to])
  82.         {
  83.             dfsLca(to);
  84.             ord.push_back(key[v]);
  85.         }
  86.     }
  87. }
  88.  
  89. int findmin(int v, int l, int r, int lv, int rv)
  90. {
  91.     if (l == lv && r == rv)
  92.         return tree[v];
  93.  
  94.     int m = (l + r) / 2;
  95.     if (m >= rv)
  96.         return findmin(2 * v + 1, l, m, lv, rv);
  97.     else
  98.         if (m <= lv)
  99.             return findmin(2 * v + 2, m, r, lv, rv);
  100.     return min(findmin(2 * v + 1, l, m, lv, m), findmin(2 * v + 2, m, r, m, rv));
  101. }
  102.  
  103. void inc(int v, int l, int r, int k)
  104. {
  105.     if (l + 1 == r)
  106.     {
  107.         tree[v] = ord[k];
  108.         return;
  109.     }
  110.     int m = (l + r) / 2;
  111.     if (m > k)
  112.         inc(2 * v + 1, l, m, k);
  113.     else
  114.         inc(2 * v + 2, m, r, k);
  115.     tree[v] = min(tree[2 * v + 1], tree[2 * v + 2]);
  116. }
  117.  
  118. void modify(int line, int v, int l, int r, int k)
  119. {
  120.     if (l + 1 == r)
  121.     {
  122.         t[line][v] = val[k];
  123.         return;
  124.     }
  125.     int m = (l + r) / 2;
  126.     if (m > pos[k].second)
  127.         modify(line, 2 * v + 1, l, m, k);
  128.     else
  129.         modify(line, 2 * v + 2, m, r, k);
  130.     t[line][v] = max(t[line][2 * v + 1], t[line][2 * v + 2]);
  131. }
  132.  
  133. long long findmax(int line, int v, int l, int r, int lv, int rv)
  134. {
  135.     if (l == lv && r == rv)
  136.         return t[line][v];
  137.     int m = (l + r) / 2;
  138.     if (m >= rv)
  139.         return findmax(line, 2 * v + 1, l, m, lv, rv);
  140.     else
  141.         if (m <= lv)
  142.             return findmax(line, 2 * v + 2, m, r, lv, rv);
  143.     return max(findmax(line, 2 * v + 1, l, m, lv, m), findmax(line, 2 * v + 2, m, r, m, rv));
  144. }
  145.  
  146. long long sum(int a, int b)
  147. {
  148.     long long m = 0;
  149.     while (a != 0 && pos[a].first != pos[b].first)
  150.     {
  151.         int d = chain[pos[a].first].back();
  152.         m = max(m, findmax(pos[a].first, 0, 0, chain[pos[a].first].size(), pos[a].second, chain[pos[a].first].size()));
  153.         a = par[d];
  154.     }
  155.     return max(m, findmax(pos[a].first, 0, 0, chain[pos[a].first].size(), pos[a].second, pos[b].second + 1));
  156. }
  157.  
  158. int main()
  159. {
  160.     int n, x, y;
  161.     cin >> n;
  162.     g.resize(n);
  163.  
  164.     for (int i = 0; i < n - 1; i++)
  165.     {
  166.         cin >> x >> y;
  167.         x--; y--;
  168.         g[x].push_back(y);
  169.         g[y].push_back(x);
  170.     }
  171.  
  172.     fill(used, used + n, 0);
  173.     fill(num, num + n, 0);
  174.     par[0] = 0;
  175.     dfsCount(0);
  176.  
  177.     fill(used, used + n, 0);
  178.     chain.resize(n);
  179.     dfsChain(0);
  180.  
  181.     fill(used, used + n, 0);
  182.     fill(fin, fin + n, -1);
  183.     dfsLca(0);
  184.  
  185.     for (int i = 0; i < ord.size(); i++)
  186.         inc(0, 0, ord.size(), i);
  187.  
  188.     int m;
  189.     char c;
  190.     cin >> m;
  191.  
  192.     fill(val, val + n, 0);
  193.     t.resize(chain.size());
  194.     for (int i = 0; i < t.size(); i++)
  195.         t[i].resize(chain[i].size() * 4 + 10);
  196.     for (int i = 0; i < m; i++)
  197.     {
  198.         cin >> c >> x >> y;
  199.         x--; y--;
  200.         if (c == 'I')
  201.         {
  202.             y++;
  203.             val[x] += y;
  204.             int line = pos[x].first;
  205.             modify(line, 0, 0, chain[line].size(), x);
  206.         }
  207.         else
  208.         {
  209.             if (fin[x] > fin[y])
  210.                 swap(x, y);
  211.             int lca = unkey[findmin(0, 0, ord.size(), fin[x], fin[y] + 1)];
  212.             cout << max(sum(x, lca), sum(y, lca)) << endl;
  213.         }
  214.     }
  215.  
  216.     return 0;
  217. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement