From 0ee882a18b7b4d7f8deab99b24c4ff82dd77b115 Mon Sep 17 00:00:00 2001
From: Bruno Freitas Tissei <bft15@inf.ufpr.br>
Date: Wed, 15 May 2019 15:46:41 -0300
Subject: [PATCH] Simply code

Signed-off-by: Bruno Freitas Tissei <bft15@inf.ufpr.br>
---
 algorithms/geometry/convex_hull.cpp         |  3 +-
 algorithms/graph/centroid_decomposition.cpp |  6 +-
 algorithms/graph/dinic.cpp                  | 37 ++++------
 algorithms/graph/lca.cpp                    | 24 +++----
 algorithms/graph/topological_sort.cpp       |  7 +-
 algorithms/math/fft.cpp                     | 16 +++--
 algorithms/string/kmp.cpp                   |  6 +-
 algorithms/string/z-function.cpp            |  3 +-
 algorithms/structure/ball_tree.cpp          | 10 ++-
 algorithms/structure/bit.cpp                |  1 -
 algorithms/structure/bit2d.cpp              |  1 -
 algorithms/structure/lazy_segment_tree.cpp  | 14 ++--
 algorithms/structure/segment_tree.cpp       | 73 ++++++++-----------
 algorithms/structure/sqrt_decomposition.cpp | 59 +++++++++-------
 algorithms/structure/trie.cpp               | 77 +++++----------------
 15 files changed, 144 insertions(+), 193 deletions(-)

diff --git a/algorithms/geometry/convex_hull.cpp b/algorithms/geometry/convex_hull.cpp
index 5c94162..e396b6e 100644
--- a/algorithms/geometry/convex_hull.cpp
+++ b/algorithms/geometry/convex_hull.cpp
@@ -10,7 +10,8 @@ struct ConvexHull {
   // cross > 0, clockwise if cross < 0, and collinear 
   // if cross = 0.
   double cross(point a, point b, point c) {
-    return (b.fi-a.fi)*(c.se-a.se) - (b.se-a.se)*(c.fi-a.fi);
+    return (b.fi - a.fi) * (c.se - a.se) - \
+      (b.se - a.se) * (c.fi - a.fi);
   }
 
   vector<int> run(const vector<point> &v) {
diff --git a/algorithms/graph/centroid_decomposition.cpp b/algorithms/graph/centroid_decomposition.cpp
index 74a6d82..d9aea65 100644
--- a/algorithms/graph/centroid_decomposition.cpp
+++ b/algorithms/graph/centroid_decomposition.cpp
@@ -29,9 +29,7 @@ struct CentroidDecomposition {
 
   void init() {
     fill(all(marked), 0);
-
-    // Assuming vertices are 0-indexed
-    build(0);
+    build(0); // 0-indexed vertices
   }
 
   void build(int x, int p = -1) {
@@ -52,11 +50,9 @@ struct CentroidDecomposition {
     for (auto i : graph[x])
       if (i != p && !marked[i])
         size[x] += dfs(i, x);
-
     return size[x];
   }
 
-  // Finds centroid.
   int get_centroid(int x, int n, int p = -1) {
     for (auto i : graph[x])
       if (i != p && size[i] > n / 2 && !marked[i])
diff --git a/algorithms/graph/dinic.cpp b/algorithms/graph/dinic.cpp
index b74d047..ca0d170 100644
--- a/algorithms/graph/dinic.cpp
+++ b/algorithms/graph/dinic.cpp
@@ -4,13 +4,7 @@
 /// Complexity (Space): O(V + E)
 
 struct Dinic {
-  struct Edge {
-    int u, flow, cap, rev;
-
-    Edge(int u, int flow, int cap, int rev) :
-      u(u), flow(flow), cap(cap), rev(rev) 
-    {}
-  };
+  struct Edge { int u, f, c, r; };
 
   int N;
   vector<int> depth, start;
@@ -22,11 +16,11 @@ struct Dinic {
 
   // Adds edge (s, t) with capacity c to the graph.
   void add_edge(int s, int t, int c) {
-    Edge forward(t, 0, c, graph[t].size());
-    Edge backward(s, 0, 0, graph[s].size());
+    Edge forw = { t, 0, c, graph[t].size() };
+    Edge back = { s, 0, 0, graph[s].size() };
 
-    graph[s].pb(forward);
-    graph[t].pb(backward);
+    graph[s].pb(forw);
+    graph[t].pb(back);
   }
 
   bool bfs(int s, int t) {
@@ -39,31 +33,30 @@ struct Dinic {
     while (!Q.empty()) {
       int v = Q.front(); Q.pop();
 
-      for (auto i : graph[v]) {
-        if (depth[i.u] == -1 && i.flow < i.cap) {
+      for (auto i : graph[v])
+        if (depth[i.u] == -1 && i.f < i.c) {
           depth[i.u] = depth[v] + 1;
           Q.push(i.u);
         }
-      }
     }
 
     return depth[t] != -1;
   }
 
-  int dfs(int s, int t, int flow) {
+  int dfs(int s, int t, int f) {
     if (s == t)
-      return flow;
+      return f;
 
     for ( ; start[s] < graph[s].size(); ++start[s]) {
       Edge &e = graph[s][start[s]];
 
-      if (depth[e.u] == depth[s] + 1 && e.flow < e.cap) {
-        int min_flow = dfs(e.u, t, min(flow, e.cap - e.flow));
+      if (depth[e.u] == depth[s] + 1 && e.f < e.c) {
+        int min_f = dfs(e.u, t, min(f, e.c - e.f));
 
-        if (min_flow > 0) {
-          e.flow += min_flow;
-          graph[e.u][e.rev].flow -= min_flow;
-          return min_flow;
+        if (min_f > 0) {
+          e.f += min_f;
+          graph[e.u][e.r].f -= min_f;
+          return min_f;
         }
       }
     }
diff --git a/algorithms/graph/lca.cpp b/algorithms/graph/lca.cpp
index 66b1c2d..a1ee78e 100644
--- a/algorithms/graph/lca.cpp
+++ b/algorithms/graph/lca.cpp
@@ -17,23 +17,18 @@ struct LCA {
     h(N), 
     par(N, vector<int>(MAXLOG)), 
     cost(N, vector<int>(MAXLOG))
-  {
-    init();
-  }
+  { init(); }
 
   void init() {
     for (auto &i : par)
       fill(all(i), -1);
     for (auto &i : cost)
       fill(all(i), 0);
-
-    // Assuming root is 0
-    dfs(0);
+    dfs(0); // 0-indexed vertices
   }
 
-  inline int op(int a, int b) {
-    // or max(a, b)
-    return a + b;
+  int op(int a, int b) {
+    return a + b; // or max(a, b)
   }
 
   void dfs(int v, int p = -1, int c = 0) {
@@ -46,9 +41,8 @@ struct LCA {
     for (int i = 1; i < MAXLOG; ++i)
       if (par[v][i - 1] != -1) {
         par[v][i] = par[par[v][i - 1]][i - 1];
-        cost[v][i] = op(cost[v][i], 
-            op(cost[par[v][i-1]][i-1], 
-               cost[v][i-1]));
+        cost[v][i] = op(cost[v][i], op(cost[v][i-1],
+              cost[par[v][i-1]][i-1]));
       }
 
     for (auto u : graph[v]) 
@@ -85,8 +79,10 @@ struct LCA {
       }
 
     #ifdef COST
-      if (p == q) return ans;
-      else return op(ans, op(cost[p][0], cost[q][0]));
+      if (p == q) 
+        return ans;
+      else 
+        return op(ans, op(cost[p][0], cost[q][0]));
     #else
       return par[p][0];
     #endif
diff --git a/algorithms/graph/topological_sort.cpp b/algorithms/graph/topological_sort.cpp
index 61390dd..3bbf5ed 100644
--- a/algorithms/graph/topological_sort.cpp
+++ b/algorithms/graph/topological_sort.cpp
@@ -12,9 +12,7 @@ struct TopologicalSort {
 
   TopologicalSort(int N) : N(N), vis(N) {}
 
-  void init() {
-    fill(all(vis), 0);
-  }
+  void init() { fill(all(vis), 0); }
 
   bool dfs(int x) {
     vis[x] = 1;
@@ -32,7 +30,8 @@ struct TopologicalSort {
     return false;
   }
 
-  /// Returns whether graph contains cycle or not.
+  // Returns whether graph contains cycle 
+  // or not.
   bool run(vector<int> &tsort) {
     init();
 
diff --git a/algorithms/math/fft.cpp b/algorithms/math/fft.cpp
index dfc807b..d0a9399 100644
--- a/algorithms/math/fft.cpp
+++ b/algorithms/math/fft.cpp
@@ -44,17 +44,19 @@ struct FFT {
 
     // Construct rev vector
     for (int i = 0; i < (1 << nbase); ++i)
-      rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (nbase - 1));
+      rev[i] = (rev[i >> 1] >> 1) + \
+               ((i & 1) << (nbase - 1));
 
     // Construct roots vector
     for (int base = 1; base < nbase; ++base) {
       float angle = 2 * M_PI / (1 << (base + 1));
 
       for (int i = 1 << (base - 1); i < (1 << base); ++i) {
-        float angle_i = angle * (2 * i + 1 - (1 << base));
+        float angle_i = angle * (2*i + 1 - (1 << base));
 
         roots[i << 1] = roots[i];
-        roots[(i << 1) + 1] = Complex(cos(angle_i), sin(angle_i));
+        roots[(i << 1) + 1] = Complex(cos(angle_i),
+            sin(angle_i));
       }
     }
   }
@@ -77,7 +79,9 @@ struct FFT {
     }
   }
 
-  vector<int> multiply(const vector<int> &a, const vector<int> &b) {
+  vector<int> multiply(const vector<int> &a, 
+      const vector<int> &b) 
+  {
     int nbase, need = a.size() + b.size() + 1;
 
     for (nbase = 0; (1 << nbase) < need; ++nbase);
@@ -97,10 +101,10 @@ struct FFT {
     Complex r(0, -0.25 / size);
     for (int i = 0; i <= (size >> 1); ++i) {
       int j = (size - i) & (size - 1);
-      Complex z = (fa[j] * fa[j] - conj(fa[i] * fa[i])) * r;
+      Complex z = (fa[j]*fa[j] - conj(fa[i]*fa[i])) * r;
 
       if (i != j)
-        fa[j] = (fa[i] * fa[i] - conj(fa[j] * fa[j])) * r;
+        fa[j] = (fa[i]*fa[i] - conj(fa[j]*fa[j])) * r;
 
       fa[i] = z;
     }
diff --git a/algorithms/string/kmp.cpp b/algorithms/string/kmp.cpp
index 4fee58d..8f05cd1 100644
--- a/algorithms/string/kmp.cpp
+++ b/algorithms/string/kmp.cpp
@@ -38,8 +38,10 @@ struct KMP {
         occurs.push_back(i - j);
         j = table[j - 1];
       } else if (i < txt.size() && patt[j] != txt[i]) {
-        if (j > 0) j = table[j - 1];
-        else i++;
+        if (j > 0) 
+          j = table[j - 1];
+        else 
+          i++;
       }
     }
 
diff --git a/algorithms/string/z-function.cpp b/algorithms/string/z-function.cpp
index 650405d..678df3e 100644
--- a/algorithms/string/z-function.cpp
+++ b/algorithms/string/z-function.cpp
@@ -13,7 +13,8 @@ struct ZFunction {
       if (i <= r)
         z[i] = min(r - i + 1, z[i - l]);
 
-      for (; i + z[i] < n && s[z[i]] == s[i + z[i]]; ++z[i]);
+      while (i + z[i] < n && s[z[i]] == s[i + z[i]])
+        z[i]++;
 
       if (i + z[i] - 1 > r) {
         l = i; 
diff --git a/algorithms/structure/ball_tree.cpp b/algorithms/structure/ball_tree.cpp
index 6ef5749..c4cadce 100644
--- a/algorithms/structure/ball_tree.cpp
+++ b/algorithms/structure/ball_tree.cpp
@@ -25,7 +25,9 @@ struct BallTree {
     return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
   }
 
-  pair<double, int> get_radius(point &center, vector<point> &ps) {
+  pair<double,int> get_radius(point &center, 
+      vector<point> &ps) 
+  {
     int ind = 0;
     double dist, radius = -1.0;
 
@@ -38,7 +40,7 @@ struct BallTree {
       }
     }
 
-    return pair<double, int>(radius, ind);
+    return pair<double,int>(radius, ind);
   }
 
   void get_center(const vector<point> &ps, point &center) {
@@ -116,7 +118,9 @@ struct BallTree {
     return n;
   }
   
-  void search(Node *n, point t, multiset<double> &pq, int &k) {
+  void search(Node *n, point t, multiset<double> &pq, 
+      int &k) 
+  {
     if (n->left == nullptr && n->right == nullptr) {
       double dist = distance(t, n->center);
 
diff --git a/algorithms/structure/bit.cpp b/algorithms/structure/bit.cpp
index 665f9ef..5db0e38 100644
--- a/algorithms/structure/bit.cpp
+++ b/algorithms/structure/bit.cpp
@@ -17,7 +17,6 @@ struct BIT {
     int sum = 0;
     for (; idx > 0; idx -= (idx & -idx))
       sum += tree[idx];
-
     return sum;
   }
 
diff --git a/algorithms/structure/bit2d.cpp b/algorithms/structure/bit2d.cpp
index c20a664..748f77c 100644
--- a/algorithms/structure/bit2d.cpp
+++ b/algorithms/structure/bit2d.cpp
@@ -23,7 +23,6 @@ struct BIT2D {
     for (; idx > 0; idx -= (idx & -idx))
       for (int m = idy; m > 0; m -= (m & -m))
         sum += tree[idx][m];
-
     return sum;
   }
 
diff --git a/algorithms/structure/lazy_segment_tree.cpp b/algorithms/structure/lazy_segment_tree.cpp
index 4fbf1ad..fdb4c16 100644
--- a/algorithms/structure/lazy_segment_tree.cpp
+++ b/algorithms/structure/lazy_segment_tree.cpp
@@ -25,7 +25,9 @@ struct LazySegmentTree {
   inline int left(int x) { return (x << 1); }
   inline int right(int x) { return (x << 1) + 1; }
 
-  void build(const vector<int> &v, int node=1, int a=0, int b=N-1) {
+  void build(const vector<int> &v, int node = 1, 
+      int a = 0, int b = N - 1) 
+  {
     if (a > b) 
       return;
 
@@ -42,7 +44,7 @@ struct LazySegmentTree {
 
   void push(int node, int a, int b, int val) {
     tree[node] += val;
-    // tree[node] += (b - a + 1) * val; (for Range Sum Query)
+    // tree[node] += (b - a + 1)*val; (for Range Sum Query)
 
     if (a != b) {
       lazy[left(node)] += val;
@@ -52,7 +54,9 @@ struct LazySegmentTree {
     lazy[node] = 0;
   }
 
-  void update(int i, int j, int val, int node=1, int a=0, int b=N-1) {
+  void update(int i, int j, int val, int node = 1,
+      int a = 0, int b = N - 1) 
+  {
     if (lazy[node] != 0)
       push(node, a, b, lazy[node]);
 
@@ -70,7 +74,9 @@ struct LazySegmentTree {
     tree[node] = tree[left(node)] + tree[right(node)];
   }
 
-  int query(int i, int j, int node=1, int a=0, int b=N-1) {
+  int query(int i, int j, int node = 1,
+      int a = 0, int b = N - 1)
+  {
     if (a > b || a > j || b < i)
       return 0;
 
diff --git a/algorithms/structure/segment_tree.cpp b/algorithms/structure/segment_tree.cpp
index 5298d80..4014e04 100644
--- a/algorithms/structure/segment_tree.cpp
+++ b/algorithms/structure/segment_tree.cpp
@@ -1,67 +1,48 @@
 /// Segment Tree
 ///
 /// Complexity (Time):
-///   Build  -> O(n log n)
 ///   Update -> O(log n)
 ///   Query  -> O(log n)
 /// Complexity (Space): O(n)
 
-int N;
 struct SegmentTree {
+  int N;
   vector<int> tree;
 
-  SegmentTree(const vector<int> &v) : 
-    tree(MAX*4) 
-  {
-    init();
-    build(v);
-  }
-
-  void init() { fill(all(tree), 0); }
-
-  inline int left(int x) { return (x << 1); }
-  inline int right(int x) { return (x << 1) + 1; }
+  Tree(int N) : 
+    N(N), tree(2 * N, 0)
+  {}
 
-  void build(const vector<int> &v, int node=1, int a=0, int b=N-1) {
-    if (a > b) 
-      return;
-
-    if (a == b) {
-      tree[node] = v[a];
-      return;
-    }
-
-    int mid = (a + b) / 2;
-    build(v, left(node), a, mid);
-    build(v, right(node), mid + 1, b);
-    tree[node] = tree[left(node)] + tree[right(node)];
+  // Base depends on 'op':
+  // op: a + b -> base: 0
+  // op: min(a,b) -> base: inf
+  int base = -inf;
+  int op(int a, int b) { 
+    return max(a, b); 
   }
 
-  void update(int idx, int val, int node=1, int a=0, int b=N-1) {
-    if (a > b || a > idx || b < idx) 
-      return;
+  void update(int idx, int val) {
+    idx += N;
+    tree[idx] = val;
 
-    if (a == b) {
-      tree[node] = val;
-      return;
+    while (idx > 1) {
+      tree[idx / 2] = op(tree[idx & ~1], tree[idx | 1]);
+      idx /= 2;
     }
-
-    int mid = (a + b) / 2;
-    update(idx, val, left(node), a, mid);
-    update(idx, val, right(node), mid + 1, b);
-    tree[node] = tree[left(node)] + tree[right(node)];
   }
 
-  int query(int i, int j, int node=1, int a=0, int b=N-1) {
-    if (a > b || a > j || b < i) 
-      return 0;
+  int query(int l, int r) {
+    int ra = base, rb = base;
+    l += N, r += N;
 
-    if (i <= a && b <= j) 
-      return tree[node];
+    while (l < r) {
+      if (l % 2) ra = op(ra, tree[l++]);
+      if (r % 2) rb = op(tree[--r], rb);
+
+      l >>= 1;
+      r >>= 1;
+    }
 
-    int mid = (a + b) / 2;
-    int q1 = query(i, j, left(node), a, mid);
-    int q2 = query(i, j, right(node), mid + 1, b);
-    return q1 + q2;
+    return op(ra, rb);
   }
 };
diff --git a/algorithms/structure/sqrt_decomposition.cpp b/algorithms/structure/sqrt_decomposition.cpp
index c73a3ac..1fb9f27 100644
--- a/algorithms/structure/sqrt_decomposition.cpp
+++ b/algorithms/structure/sqrt_decomposition.cpp
@@ -6,38 +6,47 @@
 ///   Update     -> O(1)
 /// Complexity (space): O(n)
 
-int v[MAX];
-int block[MAX];
-int block_size;
+struct SqrtDecomposition {
+  int block_size;
+  vector<int> v, block;
 
-void update(int idx, int val) {
-  block[idx / block_size] += val - v[idx];
-  v[idx] = val;
-}
+  SqrtDecomposition(vector<int> v) :
+    v(v), block(v.size())
+  { init(); }
 
-int query(int l, int r) {
-  int ans = 0;
+  void init() {
+    preprocess(v.size());
+  }
+
+  void update(int idx, int val) {
+    block[idx / block_size] += val - v[idx];
+    v[idx] = val;
+  }
 
-  for (; l < r && ((l % block_size) != 0); ++l)
-    ans += v[l];
+  int query(int l, int r) {
+    int ans = 0;
 
-  for (; l + block_size <= r; l += block_size)
-    ans += block[l / block_size];
+    for (; l < r && ((l % block_size) != 0); ++l)
+      ans += v[l];
 
-  for (; l <= r; ++l)
-    ans += v[l];
+    for (; l + block_size <= r; l += block_size)
+      ans += block[l / block_size];
 
-  return ans;
-}
+    for (; l <= r; ++l)
+      ans += v[l];
+
+    return ans;
+  }
 
-void preprocess(int n) {
-  block_size = sqrt(n);
+  void preprocess(int n) {
+    block_size = sqrt(n);
 
-  int idx = -1;
-  for (int i = 0; i < n; ++i) {
-    if (i % block_size == 0)
-      block[++idx] = 0;
+    int idx = -1;
+    for (int i = 0; i < n; ++i) {
+      if (i % block_size == 0)
+        block[++idx] = 0;
 
-    block[idx] += v[i];
+      block[idx] += v[i];
+    }
   }
-}
+};
diff --git a/algorithms/structure/trie.cpp b/algorithms/structure/trie.cpp
index 0af8e62..b6542bf 100644
--- a/algorithms/structure/trie.cpp
+++ b/algorithms/structure/trie.cpp
@@ -5,15 +5,18 @@
 ///   Search -> O(m)
 /// Complexity (Space): O(alphabet_size * N)
 
-/// ========== Trie for String ==========
+template <typename T>
 struct Trie {
-  int N, states;
+  int states;
 
   vector<int> ending;
   vector<vector<int>> trie;
 
-  Trie(int N) :
-    N(N), ending(N), trie(N, vector<int>(26))
+  // Number of words (N) and number of letters per word
+  // (L), and number of letters in alphabet (alph).
+  Trie(int N, int L, int alph) :
+    ending(N * L), 
+    trie(N * L, vector<int>(alph))
   { init(); }
 
   void init() {
@@ -22,71 +25,29 @@ struct Trie {
       fill(all(i), -1);
   }
 
-  void insert(string word) {
-    int node = 0;
-
-    for (int i = 0; i < word.size(); ++i) {
-      int b = word[i] - 'a';
-
-      if (trie[node][b] == -1)
-        trie[node][b] = ++states;
-      node = trie[node][b];
-    }
-
-    ending[node] = true;
-  }
-
-  bool search(string word) {
-    int node = 0;
-
-    for (int i = 0; i < word.size(); ++i) {
-      node = trie[node][word[i] - 'a'];
-      if (node == -1)
-        return false;
-    }
-
-    return ending[node];
-  }
-};
-
-
-/// ========== Trie for Integer ==========
-struct Trie {
-  int N, states;
-
-  vector<int> ending;
-  vector<vector<int>> trie;
+  int idx(string x, int i) { return x[i] - 'a'; }
+  int idx(int x, int i) { return !!(x & (1 << i)); }
 
-  Trie(int N) :
-    N(N), ending(N), trie(N, vector<int>(2))
-  {}
+  int len(int x) { return 32; }
+  int len(string x) { return x.size(); }
 
-  void init() {
-    states = 0;
-    for (auto &i : trie)
-      fill(all(i), -1);
-  }
-
-  void insert(int x) {
+  void insert(T x) {
     int node = 0;
 
-    for (int i = 30; i >= 0; --i) {
-      int b = !!(x & (1 << i));
-
-      if (trie[node][b] == -1)
-        trie[node][b] = ++states;
-      node = trie[node][b];
+    for (int i = 0; i < len(x); ++i) {
+      if (trie[node][idx(x, i)] == -1)
+        trie[node][idx(x, i)] = ++states;
+      node = trie[node][idx(x, i)];
     }
 
     ending[node] = true;
   }
 
-  bool search(int x) {
+  bool search(T x) {
     int node = 0;
 
-    for (int i = 30; i >= 0; --i) {
-      int b = !!(x & (1 << i));
-      node = trie[node][b];
+    for (int i = 0; i < len(x); ++i) {
+      node = trie[node][idx(x, i)];
       if (node == -1)
         return false;
     }
-- 
GitLab