Bekzhan

HLD

Feb 18th, 2013
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.74 KB | None | 0 0
  1. #pragma comment(linker, "/STACK:32000000")
  2. #include <iostream>
  3. #include <cstdio>
  4. #include <vector>
  5.  
  6. using namespace std;
  7.  
  8. vector <vector <int> > g, lca_arr, decomp, t;
  9.  
  10. vector <int> anc, sz, tin, tout, heavy, top, val;
  11.  
  12. vector <pair <int, int> > pos;
  13.  
  14. int n, l, timer;
  15.  
  16. bool is_heavy(int v, int to)
  17. {
  18.     if (sz[to] * 2 >= sz[v])
  19.         return true;
  20.  
  21.     return false;  
  22. }
  23.  
  24. void dfs(int v, int pr = 0)
  25. {
  26.     anc[v] = pr;
  27.  
  28.     tin[v] = timer++;
  29.  
  30.     sz[v] = 1;
  31.  
  32.     lca_arr[v][0] = pr;
  33.  
  34.     for (int i = 1; i <= l; i++)
  35.         lca_arr[v][i] = lca_arr[lca_arr[v][i - 1]][i - 1];
  36.  
  37.     for (size_t i = 0; i < g[v].size(); i++)
  38.         if (pr != g[v][i])
  39.             {
  40.                 dfs(g[v][i], v);
  41.                 sz[v] += sz[g[v][i]];
  42.             }
  43.  
  44.     for (size_t i = 0; i < g[v].size(); i++)
  45.         if (g[v][i] != pr && is_heavy(v, g[v][i]))
  46.             heavy[v] = g[v][i];
  47.  
  48.     tout[v] = timer++;
  49. }
  50.  
  51. void init()
  52. {
  53.     while ((1 << l) <= n)
  54.         l++;
  55.  
  56.     lca_arr.assign(n, vector <int> (l + 1));
  57.  
  58.     g.resize(n);
  59.     anc.resize(n);
  60.     sz.resize(n);
  61.     tin.resize(n);
  62.     tout.resize(n);
  63.     heavy.resize(n, -1);
  64.     pos.resize(n);
  65.     val.resize(n);
  66.  
  67.     timer = 0;
  68. }
  69.  
  70. void build_hld()
  71. {
  72.     for (int i = 0; i < n; i++)
  73.         {
  74.             if (heavy[i] == -1)
  75.                 {
  76.                     int v = i;
  77.  
  78.                     decomp.resize(decomp.size() + 1);
  79.  
  80.                     top.resize(top.size() + 1);
  81.  
  82.                     decomp.back().push_back(v);
  83.  
  84.                     int f = decomp.size() - 1;
  85.  
  86.                     int s = 0;
  87.  
  88.                     pos[v] = make_pair(f, s++);
  89.                    
  90.                     if (is_heavy(anc[v], v))
  91.                         {
  92.                             v = anc[v];
  93.  
  94.                             while (true)
  95.                                 {
  96.                                     decomp.back().push_back(v);
  97.  
  98.                                     pos[v] = make_pair(f, s++);
  99.  
  100.                                     if (v == 0 || !is_heavy(anc[v], v))
  101.                                         break;
  102.  
  103.                                     v = anc[v];
  104.                                 }
  105.  
  106.                             top.back() = anc[v];
  107.                         }  
  108.               }
  109.  
  110.         }
  111.  
  112.     t.resize(decomp.size());
  113.  
  114.     for (int i = 0; i < (int)decomp.size(); i++)
  115.         t[i].resize(decomp[i].size() * 4);
  116. }
  117.  
  118. void upd(int v, int l, int r, int ind, int pos)
  119. {
  120.     //cout << l << ' ' << r << ' ' << v << ' ' << pos << ' ' << endl;
  121.  
  122.     if (l > r)
  123.         return;
  124.  
  125.     if (pos < l || pos > r)
  126.         return;
  127.  
  128.     if (l == r)
  129.         {
  130.             if (l == pos)
  131.                 t[ind][v] = val[decomp[ind][pos]];
  132.            
  133.             return;
  134.         }
  135.  
  136.     int m = (l + r) >> 1;
  137.  
  138.     upd(v << 1, l, m, ind, pos);
  139.     upd((v << 1) + 1, m + 1, r, ind, pos);
  140.  
  141.     t[ind][v] = max(t[ind][v << 1], t[ind][(v << 1) + 1]);
  142. }
  143.  
  144. int query(int v, int l, int r, int t_l, int t_r, int ind)
  145. {
  146.     //cout << l << ' ' << r << endl;
  147.     if (l > r)
  148.         return 0;
  149.  
  150.     if (l == r && l >= t_l && l <= t_r)
  151.         return t[ind][v];
  152.  
  153.     if (l >= t_l && r <= t_r)
  154.         return t[ind][v];
  155.  
  156.     if (l > t_r || r < t_l)
  157.         return 0;
  158.  
  159.     int m = (l + r) >> 1;
  160.  
  161.     int ans = query(v << 1, l, m, t_l, t_r, ind);
  162.     ans = max(ans, query((v << 1) + 1, m + 1, r, t_l, t_r, ind));
  163.  
  164.     return ans;
  165. }
  166.  
  167. bool upper(int a, int b)
  168. {
  169.     return (tin[a] <= tin[b] && tout[a] >= tout[b]);
  170. }
  171.  
  172. int lca(int a, int b)
  173. {
  174.     if (upper(a, b))
  175.         return a;
  176.  
  177.     if (upper(b, a))
  178.         return b;
  179.  
  180.     for (int i = l; i >= 0; i--)
  181.         if (!upper(lca_arr[a][i], b))
  182.             a = lca_arr[a][i];
  183.  
  184.     return lca_arr[a][0];
  185. }
  186.  
  187. int f(int a, int q)
  188. {
  189.     int ans1 = 0;
  190.     //cout << a + 1 << ' ' << q + 1 << endl;
  191.  
  192.     if (pos[a].first == pos[q].first)
  193.         {
  194.             ans1 = query(1, 0, decomp[pos[a].first].size() - 1, min(pos[a].second, pos[q].second), max(pos[a].second, pos[q].second), pos[a].first);
  195.         }
  196.     else
  197.         {
  198.             ans1 = query(1, 0, decomp[pos[a].first].size() - 1, pos[a].second, decomp[pos[a].first].size() - 1, pos[a].first);
  199.             a = top[pos[a].first];
  200.  
  201.             //cout << a << endl;
  202.  
  203.             while (a != 0 && pos[a].first != pos[q].first)
  204.                 {
  205.                     ans1 = max(ans1, t[pos[a].first][1]);
  206.                     a = top[pos[a].first];
  207.                 }
  208.  
  209.             ans1 = max(ans1, query(1, 0, decomp[pos[q].first].size() - 1, 0, pos[q].second, pos[q].first));
  210.         }
  211.  
  212.     return ans1;   
  213. }
  214.  
  215. int get_ans(int a, int b)
  216. {
  217.     if (pos[a].first == pos[b].first)
  218.         {
  219.             return query(1, 0, decomp[pos[a].first].size() - 1, min(pos[b].second, pos[a].second), max(pos[b].second, pos[a].second), pos[a].first);
  220.         }
  221.  
  222.     int q = lca(a, b);
  223.  
  224.     return max(f(a, q), f(b, q));
  225. }
  226.  
  227. int main()
  228. {
  229.     #ifndef ONLINE_JUDGE
  230.         freopen("in", "r", stdin);
  231.     #endif
  232.  
  233.     cin >> n;
  234.  
  235.     init();
  236.  
  237.     int a, b;
  238.  
  239.     for (int i = 0; i < n - 1; i++)
  240.         {
  241.             cin >> a >> b;
  242.  
  243.             a--, b--;
  244.  
  245.             g[a].push_back(b);
  246.             g[b].push_back(a);
  247.         }
  248.  
  249.     dfs(0);
  250.  
  251.     build_hld();
  252.  
  253.     /*for (int i = 0; i < (int)decomp.size(); i++)
  254.         {
  255.             for (int j = 0; j < (int)decomp[i].size(); j++)
  256.                 cout << decomp[i][j] << ' ';
  257.  
  258.             cout << endl;
  259.         }*/
  260.        
  261.     char c;
  262.  
  263.     int m;
  264.  
  265.     cin >> m;
  266.  
  267.     for (int i = 0; i < m; i++)
  268.         {
  269.             cin >> c >> a >> b;
  270.  
  271.             if (c == 'I')
  272.                 {
  273.                     a--;
  274.                     val[a] += b;
  275.  
  276.                     upd(1, 0, decomp[pos[a].first].size() - 1, pos[a].first, pos[a].second);
  277.                 }
  278.             else
  279.                 {
  280.                     a--, b--;
  281.  
  282.                     cout << get_ans(a, b) << endl;
  283.                 }  
  284.         }
  285.  
  286.     return 0;
  287. }
Advertisement
Add Comment
Please, Sign In to add comment