Advertisement
rebornplusplus

HLD (β)

Jun 26th, 2019
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.21 KB | None | 0 0
  1. /**
  2.  * Heavy Light Decomposition
  3.  * Build Complexity O(n)
  4.  * Query Complexity O(lg^2 n)
  5.  * Call init() with number of nodes
  6.  * It's probably for the best to not do "using namespace hld"
  7. **/
  8. namespace hld {
  9.     /**
  10.      * N is the maximum number of nodes
  11.      * g is the adjacency graph
  12.      * par, lev, size corresponds to parent, depth, subtree-size
  13.      * head[u] is the starting node of the chain u is in
  14.      * in[u] to out[u] keeps the subtree indices
  15.     **/
  16.     const int N = 100000+7;
  17.     vector<int> g[N];
  18.     int par[N], lev[N], head[N], size[N], in[N], out[N];
  19.     int cur_pos, n;
  20.  
  21.     /**
  22.      * returns the size of subtree rooted at u
  23.      * maintains the child with the largest subtree at the front of g[u]
  24.      * WARNING: Don't change anything here specially with size[] if Jon Snow
  25.     **/
  26.     int dfs(int u, int p) {
  27.         size[u] = 1;
  28.         par[u] = p;
  29.         lev[u] = lev[p] + 1;
  30.         for(auto &v : g[u]) {
  31.             if(v == p) continue;
  32.             size[u] += dfs(v, u);
  33.             if(size[v] > size[g[u].front()]) {
  34.                 swap(v, g[u].front());
  35.             }
  36.         }
  37.         return size[u];
  38.     }
  39.  
  40.     /**
  41.      * decomposed the tree in an array
  42.      * note that there is no physical array here
  43.     **/
  44.     void decompose(int u, int p) {
  45.         in[u] = ++cur_pos;
  46.         for(auto &v : g[u]) {
  47.             if(v == p) continue;
  48.             head[v] = (v == g[u].front() ? head[u] : v);
  49.             decompose(v, u);
  50.         }
  51.         out[u] = cur_pos;
  52.     }
  53.  
  54.     /**
  55.      * initializes the structure with _n nodes
  56.     **/
  57.     void init(int _n, int root = 1) {
  58.         n = _n;
  59.         cur_pos = 0;
  60.         dfs(root, 0);
  61.         head[root] = root;
  62.         decompose(root, 0);
  63.     }
  64.  
  65.     /**
  66.      * checks whether p is an ancestor of u
  67.     **/
  68.     bool isances(int p, int u) {
  69.         return in[p] <= in[u] and out[u] <= out[p];
  70.     }
  71.  
  72.     /**
  73.      * Returns the maximum node value in the path u - v
  74.     **/
  75.     ll query(int u, int v) {
  76.         ll ret = -INF;
  77.         while(!isances(head[u], v)) {
  78.             ret = max(ret, seg.query(1, 1, n, in[head[u]], in[u]));
  79.             u = par[head[u]];
  80.         }
  81.         swap(u, v);
  82.         while(!isances(head[u], v)) {
  83.             ret = max(ret, seg.query(1, 1, n, in[head[u]], in[u]));
  84.             u = par[head[u]];
  85.         }
  86.         if(in[v] < in[u]) swap(u, v);
  87.         ret = max(ret, seg.query(1, 1, n, in[u], in[v]));
  88.         return ret;
  89.     }
  90.  
  91.     /**
  92.      * Adds val to subtree of u
  93.     **/
  94.     void update(int u, ll val) {
  95.         seg.update(1, 1, n, in[u], out[u], val);
  96.     }
  97. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement