halfo

Heavy Light Decomposition (Loj - 1348)

Jan 22nd, 2014
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.88 KB | None | 0 0
  1. /* in the name of ALLAH, most gracious, most merciful */
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5. const int MAX_N = int (3e4) + 7;
  6. const int MAX_E = MAX_N << 1;
  7.  
  8. int n, m, g [MAX_N];
  9. int from [MAX_E], to [MAX_E], last [MAX_E];
  10.  
  11. int cnt, tr [MAX_N];
  12. void add (int i, int v) {
  13.     for (; i <= cnt; i += i & -i) tr [i] += v;
  14. }
  15.  
  16. int get (int i) {
  17.     int s = 0;
  18.     for (; i; i -= i & -i) s += tr [i];
  19.     return s;
  20. }
  21.  
  22. int get (int i, int j) {
  23.     return get (j) - get (i - 1);
  24. }
  25.  
  26. // parent, depth, size, successor in chain
  27. int p [MAX_N], d [MAX_N], sz [MAX_N], suc [MAX_N];
  28. void dfs (int u, int par = -1) {
  29.     p [u] = par, sz [u] = 1, suc [u] = -1;
  30.     d [u] = ~par ? d [par] + 1 : 0;
  31.  
  32.     int v, mx = 0;
  33.     for (int e = last [u]; ~e; e = from [e]) {
  34.         if (par == (v = to [e])) continue;
  35.         dfs (v, u);
  36.         if (sz [v] > mx)
  37.             suc [u] = v, mx = sz [v];
  38.         sz [u] += sz [v];
  39.     }
  40. }
  41.  
  42. // chain head (head is head of himself), id in BIT
  43. int head [MAX_N], id [MAX_N];
  44. void make_chain (int u, bool in_chain = false) {
  45.     head [u] = in_chain ? head [p [u]] : u;
  46.     id [u] = ++cnt;
  47.  
  48.     if (~suc [u]) make_chain (suc [u], true);
  49.     for (int e = last [u]; ~e; e = from [e]) {
  50.         if (suc [u] == to [e] || p [u] == to [e]) continue;
  51.         make_chain (to [e]);
  52.     }
  53. }
  54.  
  55. int lca (int u, int v) {
  56.     int ret = 0;
  57.     while (head [u] != head [v]) {
  58.         if (d [head [u]] > d [head [v]]) {
  59.             ret += get (id [head [u]], id [u]);
  60.             u = p [head [u]];
  61.         } else {
  62.             ret += get (id [head [v]], id [v]);
  63.             v = p [head [v]];
  64.         }
  65.     }
  66.  
  67.     if (d [u] < d [v])
  68.         ret += get (id [u], id [v]);
  69.     else
  70.         ret += get (id [v], id [u]);
  71.     return ret;
  72. }
  73.  
  74. void init () {
  75.     cnt = 0;
  76.     memset (last, -1, sizeof last);
  77.     memset (tr, 0, sizeof tr);
  78. }
  79.  
  80. int main () {
  81. #ifdef Local
  82.     freopen ("input.txt", "r", stdin);
  83.     // freopen ("output.txt", "w", stdout);
  84. #endif
  85.     int t;
  86.     scanf ("%d", &t);
  87.  
  88.     for (int cs = 1; cs <= t; ++cs) {
  89.         scanf ("%d", &n);
  90.         init ();
  91.  
  92.         for (int i = 0; i < n; ++i)
  93.             scanf ("%d", g + i);
  94.  
  95.         int nE = 0;
  96.         for (int i = 0; i < n - 1; ++i) {
  97.             int u, v;
  98.             scanf ("%d %d", &u, &v);
  99.             to [nE] = v, from [nE] = last [u], last [u] = nE++;
  100.             to [nE] = u, from [nE] = last [v], last [v] = nE++;
  101.         }
  102.  
  103.         dfs (0);
  104.         make_chain (0);
  105.         p [0] = 0;
  106.  
  107.         for (int i = 0; i < n; ++i)
  108.             add (id [i], g [i]);
  109.  
  110.         scanf ("%d", &m);
  111.         printf ("Case %d:\n", cs);
  112.  
  113.         for (int i = 0; i < m; ++i) {
  114.             int type, u, v;
  115.             scanf ("%d %d %d", &type, &u, &v);
  116.  
  117.             if (type) add (id [u], v - get (id [u], id [u]));
  118.             else printf ("%d\n", lca (u, v));
  119.         }
  120.     }
  121.     return 0;
  122. }
Advertisement
Add Comment
Please, Sign In to add comment