diff --git a/algorithms/geometry/geometry_functions.cpp b/algorithms/geometry/geometry_functions.cpp
index 1e2a51adc0a807b5e44d9d96a9084f86a7f4dda3..e1f78a1baec50000ac933e12ef02ce3973bca201 100644
--- a/algorithms/geometry/geometry_functions.cpp
+++ b/algorithms/geometry/geometry_functions.cpp
@@ -1,6 +1,7 @@
 /// Geometry Functions
 
 #define to_deg(x) ((x * 180.0) / M_PI)
+#define to_rad(x) ((x * M_PI) / 180.0)
 
 template <typename T>
 struct Point {
@@ -16,8 +17,8 @@ struct Point {
   T cross(Point p) { return (x*p.y) - (y*p.x); }
 
   // Returns angle between this and p:
-  // atan2(y, x) is in the range [-180,180]. To get [0, 360], 
-  // atan2(-y, -x) + 180 is used
+  // atan2(y, x) is in the range [-180,180]. To 
+  // get [0, 360], atan2(-y, -x) + 180 is used
   T angle(Point p) {
     return to_deg(atan2(-cross(p), -dot(p))) + 180.0;
   }
@@ -32,6 +33,8 @@ struct Point {
     return (cross(p) / (sqrt(dot(*this))*sqrt(p.dot(p))));
   }
 
+  // Returns whether point is inside the triable
+  // abc or not.
   bool inside_triagle(Point a, Point b, Point c) {
     bool c1 = (*this - b).cross(a - b) < 0;
     bool c2 = (*this - c).cross(b - c) < 0;
diff --git a/algorithms/graph/articulations_bridges.cpp b/algorithms/graph/articulations_bridges.cpp
index fd2648439538f0c34b8d8eb5cb6afc40881bf979..d843f7017e46992d27eee8101248165e0ac5219f 100644
--- a/algorithms/graph/articulations_bridges.cpp
+++ b/algorithms/graph/articulations_bridges.cpp
@@ -5,14 +5,14 @@
 
 vector<int> graph[MAX];
 
-struct Tarjan {
+struct ArticulationsBridges {
   int N;
   vector<int> vis, par, L, low;
 
   vector<ii> brid;
   vector<int> arti;
 
-  Tarjan(int N) :
+  ArticulationsBridges(int N) :
     N(N), vis(N), par(N), L(N), low(N) {}
 
   void init() {
diff --git a/algorithms/graph/bellman_ford.cpp b/algorithms/graph/bellman_ford.cpp
index 5d54ae41244d63fb38633148d469635cb247cfe5..301d3b2145a8a7788ae5410365170123ba5cd112 100644
--- a/algorithms/graph/bellman_ford.cpp
+++ b/algorithms/graph/bellman_ford.cpp
@@ -17,7 +17,6 @@ struct BellmanFord {
     fill(all(dist), inf);
   }
 
-  // Returns distance between s and d.
   int run(int s, int d) {
     dist[s] = 0;
 
diff --git a/algorithms/graph/dinic.cpp b/algorithms/graph/dinic.cpp
index fa3c52dbd27dd1aeb51e4ea5944a2f234c42c011..1403b4436df2d07a64b98e3730598bf8739467ee 100644
--- a/algorithms/graph/dinic.cpp
+++ b/algorithms/graph/dinic.cpp
@@ -18,7 +18,6 @@ struct Dinic {
   void add_edge(int s, int t, int c) {
     Edge forw = { t, 0, c, (int) graph[t].size() };
     Edge back = { s, 0, 0, (int) graph[s].size() };
-
     graph[s].pb(forw);
     graph[t].pb(back);
   }
@@ -68,7 +67,6 @@ struct Dinic {
     int ans = 0;
     while (bfs(s, t)) {
       fill(all(start), 0);
-
       while (int flow = dfs(s, t, inf))
         ans += flow;
     }
diff --git a/algorithms/graph/edmonds_karp.cpp b/algorithms/graph/edmonds_karp.cpp
index 02eea4db659a41e77e47e42ac66c7fa4c0448a2b..4838a2bc755b19ea36d07f4d25d4d36c5c884270 100644
--- a/algorithms/graph/edmonds_karp.cpp
+++ b/algorithms/graph/edmonds_karp.cpp
@@ -50,7 +50,6 @@ struct EdmondsKarp {
 
     while (bfs(s, t)) {
       int flow = inf;
-
       for (int i = t; par[i] != -1; i = par[i])
         flow = min(flow, rg[par[i]][i]);
 
diff --git a/algorithms/graph/ford_fulkerson.cpp b/algorithms/graph/ford_fulkerson.cpp
index 90fd2bb133a80acd914dabdf04911efe853f3a61..e49ae1281d16857f9bc8ac959af26a1fed9ca33b 100644
--- a/algorithms/graph/ford_fulkerson.cpp
+++ b/algorithms/graph/ford_fulkerson.cpp
@@ -42,7 +42,6 @@ struct FordFulkerson {
 
     while (dfs(s, t)) {
       int flow = inf;
-
       for (int i = t; par[i] != -1; i = par[i])
         flow = min(flow, rg[par[i]][i]);
 
diff --git a/algorithms/graph/hopcroft_karp.cpp b/algorithms/graph/hopcroft_karp.cpp
index 78e2f89a4482d8f51206255f7ab419b7bf0fcc43..2f74606cf746cf772c4b6a9aace8e9b0538a3200 100644
--- a/algorithms/graph/hopcroft_karp.cpp
+++ b/algorithms/graph/hopcroft_karp.cpp
@@ -3,9 +3,10 @@
 /// Time: O(E * sqrt{V})
 /// Space: O(V + E)
 ///
-/// Status: Tested (GCJ18 - Round2 - B)
 /// Caution: 
 ///   - Assumes 1-indexed vertices in graph.
+///
+/// Status: Tested (GCJ18-R2B)
 
 vector<int> graph[MAX];
 
@@ -31,9 +32,8 @@ struct HopcroftKarp {
       if (matchL[l] == 0) {
         dist[l] = 0;
         Q.push(l);
-      } else {
+      } else
         dist[l] = inf;
-      }
 
     dist[0] = inf;
     while (!Q.empty()) {
diff --git a/algorithms/graph/kosaraju.cpp b/algorithms/graph/kosaraju.cpp
index 3d2ff621e72ec80fb702dfbcca3a22d6c2e0d498..209f95608ad5cdf8a579199092a549b8248b098b 100644
--- a/algorithms/graph/kosaraju.cpp
+++ b/algorithms/graph/kosaraju.cpp
@@ -36,7 +36,6 @@ struct Kosaraju {
     S.push(x);
   }
 
-  // Returns number of SCC of a graph.
   int run() {
     int scc = 0;
 
diff --git a/algorithms/graph/lca.cpp b/algorithms/graph/lca.cpp
index 70d2ed37b2849bb1ec4e5a01ecbe0bf3830858b2..151af9df76b4fdc9f2666eabf6a2781aa2163ac8 100644
--- a/algorithms/graph/lca.cpp
+++ b/algorithms/graph/lca.cpp
@@ -32,10 +32,8 @@ struct LCA {
   { init(); }
 
   void init() {
-    for (auto &i : par)
-      fill(all(i), -1);
-    for (auto &i : cost)
-      fill(all(i), 0);
+    for (auto &i : par) fill(all(i), -1); 
+    for (auto &i : cost) fill(all(i), 0);
     dfs(0); // 0-indexed vertices
   }
 
@@ -62,7 +60,6 @@ struct LCA {
         dfs(u.fi, v, u.se);
   }
 
-  // Returns LCA (or sum or max).
   int query(int p, int q) {
     int ans = 0;
 
diff --git a/algorithms/graph/prim.cpp b/algorithms/graph/prim.cpp
index 3c298730b08315494ded9fe514175467f779cc56..c4ec5b9e37a1a4446a8db3180e9cf98701510ed9 100644
--- a/algorithms/graph/prim.cpp
+++ b/algorithms/graph/prim.cpp
@@ -17,9 +17,7 @@ struct Prim {
     fill(all(vis), 0);
   }
 
-  // Returns value of MST of graph.
   int run() {
-    init();
     vis[0] = true;
 
     priority_queue<ii> pq;
diff --git a/algorithms/math/big_integer.cpp b/algorithms/math/big_integer.cpp
index 3e9a062659b10daa5dd255e8d4e4d64c02ba34ea..cb0b862825760af5af4f32479e4f894a40817838 100644
--- a/algorithms/math/big_integer.cpp
+++ b/algorithms/math/big_integer.cpp
@@ -2,75 +2,48 @@
 ///
 /// Space: O(n)
 
-#include <bits/stdc++.h>
-
-#define EPS 1e-6
-#define MOD 1000000007
-#define inf 0x3f3f3f3f
-#define llinf 0x3f3f3f3f3f3f3f3f
-
-#define fi first
-#define se second
-#define pb push_back
-#define ende '\n'
-
-#define all(x) (x).begin(), (x).end()
-#define rall(x) (x).rbegin(), (x).rend()
-#define mset(x, y) memset(&x, (y), sizeof(x))
-
-using namespace std;
-
-using ll = long long;
-using ii = pair<int,int>;
-
 const int base = 1000000000;
-const int base_digits = 9;
+const int base_d = 9;
 
-struct BigInteger {
+struct BigInt {
   int sign = 1;
   vector<int> num;
 
-  BigInteger() {}
-  BigInteger(const string &x) { read(x); }
+  BigInt() {}
+  BigInt(const string &x) { read(x); }
 
-  BigInteger operator+(const BigInteger &x) const {
-    if (sign != x.sign)
-      return *this - (-x);
+  BigInt operator+(const BigInt &x) const {
+    if (sign != x.sign) return *this - (-x);
 
-    BigInteger ans = x;
-    for (int i = 0, carry = 0; i < max(size(), x.size()) || carry; ++i) {
-      if (i == ans.size())
-        ans.push_back(0);
+    BigInt ans = x;
+    int carry = 0;
+    for (int i = 0; i < max(size(), x.size()) || carry; ++i) {
+      if (i == ans.size()) ans.push_back(0);
 
-      if (i < size())
-        ans[i] += carry + num[i];
-      else
-        ans[i] += carry;
+      if (i < size()) ans[i] += carry + num[i];
+      else ans[i] += carry;
 
       carry = ans[i] >= base;
-      if (carry)
-        ans[i] -= base;
+      if (carry) ans[i] -= base;
     }
 
     return ans;
   }
 
-  BigInteger operator-(const BigInteger& x) const {
+  BigInt operator-(const BigInt& x) const {
     if (sign != x.sign)
       return *this + (-x);
     if (abs() < x.abs())
       return -(x - *this);
 
-    BigInteger ans = *this;
-    for (int i = 0, carry = 0; i < x.size() || carry; ++i) {
-      if (i < x.size())
-        ans[i] -= carry + x[i];
-      else
-        ans[i] -= carry;
+    BigInt ans = *this;
+    int carry = 0;
+    for (int i = 0; i < x.size() || carry; ++i) {
+      if (i < x.size()) ans[i] -= carry + x[i];
+      else ans[i] -= carry;
 
       carry = ans[i] < 0;
-      if (carry)
-        ans[i] += base;
+      if (carry) ans[i] += base;
     }
 
     ans.trim();
@@ -86,7 +59,7 @@ struct BigInteger {
       sign = 1;
   }
 
-  bool operator<(const BigInteger &x) const {
+  bool operator<(const BigInt &x) {
     if (sign != x.sign)
       return sign < x.sign;
 
@@ -100,40 +73,47 @@ struct BigInteger {
     return false;
   }
 
-  bool operator>(const BigInteger &x)  const { return  (x < *this); }
-  bool operator<=(const BigInteger &x) const { return !(x < *this); }
-  bool operator>=(const BigInteger &x) const { return !(*this < x); }
-  bool operator==(const BigInteger &x) const { return !(*this < x) && !(x < *this); }
-  bool operator!=(const BigInteger &x) const { return !(*this == x); }
+  bool operator==(const BigInt &x) { 
+    return !(*this < x) && !(x < *this); 
+  }
+
+  bool operator>(const BigInt &x)  const { return  (x < *this); }
+  bool operator<=(const BigInt &x) const { return !(x < *this); }
+  bool operator>=(const BigInt &x) const { return !(*this < x); }
+  bool operator!=(const BigInt &x) const { return !(*this == x); }
+
 
   /// Handles -x (change of sign).
-  BigInteger operator-() const {
-    BigInteger ans = *this;
+  BigInt operator-() const {
+    BigInt ans = *this;
     ans.sign = -sign;
     return ans;
   }
 
   /// Returs absolute value.
-  BigInteger abs() const {
-    BigInteger ans = *this;
+  BigInt abs() const {
+    BigInt ans = *this;
     ans.sign *= ans.sign;
     return ans;
   }
 
-  /// Transforms string into BigInteger.
+  /// Transforms string into BigInt.
   void read(const string &s) {
     sign = 1;
     num.clear();
+
     int pos = 0;
-    while (pos < (int) s.size() && (s[pos] == '-' || s[pos] == '+')) {
+    while (pos < (int) s.size() && 
+        (s[pos] == '-' || s[pos] == '+')) 
+    {
       if (s[pos] == '-')
         sign = -sign;
       ++pos;
     }
 
-    for (int i = s.size() - 1; i >= pos; i -= base_digits) {
+    for (int i = s.size() - 1; i >= pos; i -= base_d) {
       int x = 0;
-      for (int j = max(pos, i - base_digits + 1); j <= i; j++)
+      for (int j = max(pos, i - base_d + 1); j <= i; j++)
         x = x * 10 + s[j] - '0';
       num.push_back(x);
     }
@@ -141,19 +121,20 @@ struct BigInteger {
     trim();
   }
 
-  friend istream& operator>>(istream &stream, BigInteger &v) {
+  friend istream& operator>>(istream &stream, BigInt &v) {
     string s; stream >> s;
     v.read(s);
     return stream;
   }
 
-  friend ostream& operator<<(ostream &stream, const BigInteger &x) {
+  friend ostream& operator<<(ostream &stream, 
+      const BigInt &x) {
     if (x.sign == -1)
       stream << '-';
 
     stream << (x.empty() ? 0 : x.back());
     for (int i = x.size() - 2; i >= 0; --i)
-      stream << setw(base_digits) << setfill('0') << x.num[i];
+      stream << setw(base_d) << setfill('0') << x.num[i];
 
     return stream;
   }
@@ -167,10 +148,3 @@ struct BigInteger {
   int &operator[](int i) { return num[i]; }
   int operator[](int i) const { return num[i]; }
 };
-
-int main() {
-  BigInteger x, y;
-  cin >> x >> y;
-  cout << x + y << ende;
-  return 0;
-}
diff --git a/algorithms/math/binary_exponentiation.cpp b/algorithms/math/binary_exponentiation.cpp
index 032382055cb6b8b621f1c1aa6f5bc4d0c1896779..bda0665f2416948c48bf68ff8ea62450ba02ad7b 100644
--- a/algorithms/math/binary_exponentiation.cpp
+++ b/algorithms/math/binary_exponentiation.cpp
@@ -4,7 +4,7 @@
 /// Space: O(1)
 
 struct BinaryExponentiation {
-  ll fast_pow(ll x, ll n) {
+  ll run(ll x, ll n) {
     ll ans = 1;
 
     while (n) {
diff --git a/algorithms/math/euler_totient.cpp b/algorithms/math/euler_totient.cpp
index 0ffdfdce57c02287edd4563fda695d365d7874ea..1fbe385abe08d1012cc99388e73e2b41ba5116be 100644
--- a/algorithms/math/euler_totient.cpp
+++ b/algorithms/math/euler_totient.cpp
@@ -7,15 +7,14 @@ struct EulerTotient {
   int run(int n) {
     int result = n;
 
-    for (int i = 2; i*i <= n; i++) {
+    for (int i = 2; i*i <= n; i++)
       if (n % i == 0) {
         while (n % i == 0) n /= i;
         result -= result / i;
       }
-    }
 
     if (n > 1)
-      result -= result / n;
+      result -= (result / n);
 
     return result;
   }
diff --git a/algorithms/math/extended_euclidean.cpp b/algorithms/math/extended_euclidean.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cddc37e2edff9ec4306f9ed7a96fdee98b0f448f
--- /dev/null
+++ b/algorithms/math/extended_euclidean.cpp
@@ -0,0 +1,21 @@
+/// Extended Euclidean algorithm
+/// 
+/// Time: O(log n)
+/// Space: O(1)
+
+struct ExtendedEuclidean {
+  int run(int a, int b, int &x, int &y) {
+    if (a == 0) {
+      x = 0, y = 1;
+      return b;
+    }
+
+    int x1, y1;
+    int g = run(b % a, a, x1, y1);
+
+    x = y1 - (b / a) * x1;
+    y = x1;
+
+    return g;
+  }
+};
diff --git a/algorithms/math/legendre.cpp b/algorithms/math/legendre.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6d1fb75b01820e2df52ad5dd023e126bd5e972f9
--- /dev/null
+++ b/algorithms/math/legendre.cpp
@@ -0,0 +1,17 @@
+/// Legendre's Formula
+///
+/// Time: O(log_p n)
+/// Space: O(1)
+
+struct Legendre {
+  int run(int n, int p) {
+    int x = 0;
+
+    while (n) {
+      n /= p;
+      x += n;
+    }
+
+    return x;
+  }
+};
diff --git a/algorithms/math/linear_recurrence.cpp b/algorithms/math/linear_recurrence.cpp
index 214ea425c7cef4312e3461f4e69b00e2a094257b..ff42e83cd907321f06098aa2e21c335556ce3b02 100644
--- a/algorithms/math/linear_recurrence.cpp
+++ b/algorithms/math/linear_recurrence.cpp
@@ -8,8 +8,8 @@
 ///   - math/matrix
 
 template <typename T>
-matrix<T> solve(ll x, ll y, ll n) {
-  matrix<T> in(2);
+matrix<T> solve(int x, int y, int n) {
+  matrix<T> in(2, 2);
 
   // Example
   in[0][0] = x % MOD;
diff --git a/algorithms/math/matrix.cpp b/algorithms/math/matrix.cpp
index 128ef5565dd3787c7178423a36975616b2c343b0..e82d439a2ab11bef34a1ad7441e11b575eba65ac 100644
--- a/algorithms/math/matrix.cpp
+++ b/algorithms/math/matrix.cpp
@@ -3,19 +3,15 @@
 /// Space: O(R * C)
 
 template <typename T>
-struct matrix {
+struct Matrix {
   int r, c;
   vector<vector<T>> m;
 
-  matrix(int k) : r(k), c(k) {
-    m = vector<vector<T>>(k, vector<T>(k, 0));
-  }
-
-  matrix(int r, int c) : r(r), c(c) {
+  Matrix(int r, int c) : r(r), c(c) {
     m = vector<vector<T>>(r, vector<T>(c, 0));
   }
 
-  matrix operator*(matrix a) {
+  Matrix operator*(Matrix a) {
     assert(r == a.c && c == a.r);
 
     Matrix res(r, c);
@@ -30,24 +26,6 @@ struct matrix {
     return res;
   }
 
-  Matrix operator+(Matrix a) {
-    Matrix res(k);
-    for (int i = 0; i < r; ++i)
-      for (int j = 0; j < c; ++j)
-        res[i][j] = m[i][j] + a[i][j];
-
-    return res;
-  }
-
-  void to_identity() {
-    assert(r == c);
-
-    for (auto &i : m)
-      fill(all(i), 0);
-    for (int i = 0; i < r; ++i)
-      m[i][i] = 1;
-  }
-
   vector<T> &operator[](int i) {
     return m[i];
   }
diff --git a/algorithms/math/modular_multiplicative_inverse.cpp b/algorithms/math/modular_multiplicative_inverse.cpp
index e52acd0581c069baa27a340306d3c5638c5178b2..5432807bd0de69ddb7fa1dedbbacb8e6d9b7c3b3 100644
--- a/algorithms/math/modular_multiplicative_inverse.cpp
+++ b/algorithms/math/modular_multiplicative_inverse.cpp
@@ -3,37 +3,20 @@
 /// Time: O(log m)
 /// Space: O(1)
 
-/// ========== Fermat's Little Theorem ==========
-/// Used when m is prime
-/// #include "binary_exponentiation.cpp"
+// ============= Fermat's Little Theorem ============
+// Used when m is prime
 
-ll mod_inverse(ll a) {
-  return fast_pow(a, MOD - 2);
+int mod_inverse(int a, int m) {
+  BinaryExponentiation bin_exp;
+  return bin_exp.run(a, m - 2);
 }
 
+// ========== Extended Euclidean Algorithm ==========
+// Used when m and a are coprime
 
-/// ========== Extended Euclidean Algorithm ==========
-/// Used when m and a are coprime
-
-ll gcd_extended(ll a, ll b, ll &x, ll &y) {
-  if (!a) {
-    x = 0;
-    y = 1;
-    return b;
-  }
-
-  ll x1, y1;
-  ll g = gcd_extended(b % a, a, x1, y1);
-
-  x = y1 - (b / a) * x1;
-  y = x1;
-
-  return g;
-}
-
-ll mod_inverse(ll a) {
-  ll x, y;
-  ll g = gcd_extended(a, MOD, x, y);
-
-  return (x % MOD + MOD) % MOD;
+int mod_inverse(int a, int m) {
+  ExtendedEuclidean ext_gcd;
+  int x, y;
+  int g = ext_gcd.run(a, m, x, y);
+  return (x % m + m) % m;
 }
diff --git a/algorithms/paradigm/longest_common_subsequence.cpp b/algorithms/paradigm/longest_common_subsequence.cpp
index e324fb170fdf7d0dbb865ea175eea30e5ca18186..9bcba82e948af1391e3534bba92602a885572709 100644
--- a/algorithms/paradigm/longest_common_subsequence.cpp
+++ b/algorithms/paradigm/longest_common_subsequence.cpp
@@ -19,7 +19,7 @@ struct LCS {
     }
 
     // The size is already at dp[n][m], now the common 
-    // subsequence is retrieved
+    // subsequence is retrieved:
 
     int idx = dp[a.size()][b.size()];
     string ans(idx, ' ');
diff --git a/algorithms/paradigm/ternary_search.cpp b/algorithms/paradigm/ternary_search.cpp
index ae1c0b759477da5bd345c0599b67ea0464a307ab..54372a96322c8c5cd1bc764b34bdd50a25401385 100644
--- a/algorithms/paradigm/ternary_search.cpp
+++ b/algorithms/paradigm/ternary_search.cpp
@@ -20,8 +20,8 @@ struct TernarySearch {
       lt = (r - l) / 3.0 + l;
       rt = ((r - l) * 2.0) / 3.0 + l;
 
-      // < | minimum of f
-      // > | maximum of f
+      // '<' for minimum of f,
+      // '>' for maximum of f
       if (f(lt) < f(rt))
         l = lt;
       else
diff --git a/algorithms/string/kmp.cpp b/algorithms/string/kmp.cpp
index 91e38f5ef7b0a5b2cf366f87efc4f71776969f86..dfc537cad74bc9a53a03df65baf666fa68776413 100644
--- a/algorithms/string/kmp.cpp
+++ b/algorithms/string/kmp.cpp
@@ -32,6 +32,7 @@ struct KMP {
       while (j >= 0 && txt[i] != patt[j]) 
         j = table[j];
       j++;
+
       if (j == patt.size()) {
         occurs.pb(i - j);
         j = table[j];
diff --git a/algorithms/structure/avl.cpp b/algorithms/structure/avl.cpp
index de4cfcc1552f08c2f10b60888241ba4145eb1f6d..5746c131f9022abdee76a23ff08f2b45bf5136bf 100644
--- a/algorithms/structure/avl.cpp
+++ b/algorithms/structure/avl.cpp
@@ -5,35 +5,26 @@
 
 struct AVL {
   struct Node {
-    int key, size, height;
+    int key, height;
     Node *left, *right;
 
-    Node(int key, int size, int height) :
-      key(key), size(size), height(height),
+    Node(int k) :
+      key(k), height(1),
       left(nullptr), right(nullptr)
     {}
 
-    void fix_height() {
-      int lh = (left == nullptr) ? 0 : left->height;
-      int rh = (right == nullptr) ? 0 : right->height;
-      height = max(lh, rh) + 1;
-    }
-
-    void fix_size() {
-      int ls = (left == nullptr) ? 0 : left->size;
-      int rs = (right == nullptr) ? 0 : right->size;
-      size = ls + rs + 1;
+    static int get_height(Node *n) {
+      return (n == nullptr) ? 0 : n->height;
     }
 
     void fix_state() {
-      fix_height();
-      fix_size();
+      height = max(Node::get_height(left), 
+          Node::get_height(left)) + 1;
     }
 
     int get_balance() {
-      int lh = (left == nullptr) ? 0 : left->height;
-      int rh = (right == nullptr) ? 0 : right->height;
-      return lh - rh;
+      return Node::get_height(left) - 
+        Node::get_height(right);
     }
   };
 
@@ -47,54 +38,49 @@ struct AVL {
 
 private:
 
-  Node *rotate_right(Node *node) {
-    Node *aux1 = node->left;
+  Node *rotate_right(Node *n) {
+    Node *aux1 = n->left;
     Node *aux2 = aux1->right;
-    aux1->right = node;
-    node->left = aux2;
-    node->fix_state();
-    aux1->fix_state();
+    aux1->right = n; aux1->fix_state();
+    n->left = aux2; n->fix_state();
     return aux1;
   }
 
-  Node *rotate_left(Node *node) {
-    Node *aux1 = node->right;
+  Node *rotate_left(Node *n) {
+    Node *aux1 = n->right;
     Node *aux2 = aux1->left;
-    aux1->left = node;
-    node->right = aux2;
-    node->fix_state();
-    aux1->fix_state();
+    aux1->left = n; aux1->fix_state();
+    n->right = aux2; n->fix_state();
     return aux1;
   }
 
-  Node *insert(Node *node, int key) {
-    if (node == nullptr) {
-      Node *new_node = new Node(key, 1, 1);
-      if (root == nullptr)
-        root = new_node;
+  Node *insert(Node *n, int key) {
+    if (n == nullptr) {
+      Node *new_node = new Node(key);
+      if (root == nullptr) root = new_node;
       return new_node;
     }
 
-    if (key < node->key)
-      node->left  = insert(node->left, key);
+    if (key < n->key)
+      n->left  = insert(n->left, key);
     else
-      node->right = insert(node->right, key);
-
-    int balance = node->get_balance();
-    node->fix_state();
-
-    if (balance > 1 && key < node->left->key) {
-      return rotate_right(node);
-    } else if (balance < -1 && key > node->right->key) {
-      return rotate_left(node);
-    } else if (balance > 1 && key > node->left->key) {
-      node->left = rotate_left(node->left);
-      return rotate_right(node);
-    } else if (balance < -1 && key < node->right->key) {
-      node->right = rotate_right(node->right);
-      return rotate_left(node);
+      n->right = insert(n->right, key);
+
+    int balance = n->get_balance();
+    n->fix_state();
+
+    if (balance > 1 && key < n->left->key) {
+      return rotate_right(n);
+    } else if (balance < -1 && key > n->right->key) {
+      return rotate_left(n);
+    } else if (balance > 1 && key > n->left->key) {
+      n->left = rotate_left(n->left);
+      return rotate_right(n);
+    } else if (balance < -1 && key < n->right->key) {
+      n->right = rotate_right(n->right);
+      return rotate_left(n);
     }
 
-    return node;
+    return n;
   }
 };
diff --git a/algorithms/structure/ball_tree.cpp b/algorithms/structure/ball_tree.cpp
deleted file mode 100644
index 687f296f25fd9744c191431a36fd5a61ee836039..0000000000000000000000000000000000000000
--- a/algorithms/structure/ball_tree.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/// Balltree
-///
-/// Time: O(n log n)
-/// Space: O(n)
-
-#define x first
-#define y second
-
-struct BallTree {
-  typedef pair<double, double> point;
-
-  struct Node {
-    double radius;
-    point center;
-
-    Node *left, *right;
-  };
-
-
-  BallTree(vector<point> &points) {
-    build(points);
-  }
-
-  double distance(point &a, point &b) {
-    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) 
-  {
-    int ind = 0;
-    double dist, radius = -1.0;
-
-    for (int i = 0; i < ps.size(); ++i) {
-      dist = distance(center, ps[i]);
-
-      if (radius < dist) {
-        radius = dist;
-        ind = i;
-      }
-    }
-
-    return pair<double,int>(radius, ind);
-  }
-
-  void get_center(const vector<point> &ps, point &center) {
-    center.x = center.y = 0;
-
-    for (auto p : ps) {
-      center.x += p.x;
-      center.y += p.y;
-    }
-
-    center.x /= (double) ps.size();
-    center.y /= (double) ps.size();
-  }
-
-  void partition(const vector<point> &ps, vector<point> &left, 
-                 vector<point> &right, int lind) 
-  {
-    int rind = 0;
-    double dist, grt = -1.0;
-    double ldist, rdist;
-
-    point rmpoint;
-    point lmpoint = ps[lind];
-
-    for (int i = 0; i < ps.size(); ++i)
-      if (i != lind) {
-        dist = distance(lmpoint, ps[i]);
-
-        if (dist > grt) {
-          grt = dist;
-          rind = i;
-        }
-      }
-
-    rmpoint = ps[rind];
-
-    left.push_back(ps[lind]);
-    right.push_back(ps[rind]);
-
-    for (int i = 0; i < ps.size(); ++i)
-      if (i != lind && i != rind) {
-        ldist = distance(ps[i], lmpoint);
-        rdist = distance(ps[i], rmpoint);
-
-        if (ldist <= rdist)
-          left.push_back(ps[i]);
-        else
-          right.push_back(ps[i]);
-      }
-  }
-
-  Node *build(vector<point> &ps) {
-    if (ps.size() == 0)
-      return nullptr;
-
-    Node *n = new Node;
-
-    if (ps.size() == 1) {
-      n->center = ps[0];
-
-      n->radius = 0.0;
-      n->right = n->left = nullptr;
-    } else {
-      get_center(ps, n->center);
-      auto rad = get_radius(n->center, ps);
-
-      vector<point> lpart, rpart;
-      partition(ps, lpart, rpart, rad.second);
-
-      n->radius = rad.first;
-      n->left = build(lpart);
-      n->right = build(rpart);
-    }
-
-    return n;
-  }
-  
-  void search(Node *n, point t, multiset<double> &pq, 
-      int &k) 
-  {
-    if (n->left == nullptr && n->right == nullptr) {
-      double dist = distance(t, n->center);
-
-      if (dist < EPS)
-        return;
-
-      else if (pq.size() < k || dist < *pq.rbegin()) {
-        pq.insert(dist);
-        if (pq.size() > k)
-          pq.erase(prev(pq.end()));
-      }
-    } else {
-      double distl = distance(t, n->left->center);
-      double distr = distance(t, n->right->center);
-
-      if (distl <= distr) {
-        if (pq.size() < k || (distl <= *pq.rbegin() + n->left->radius))
-          search(n->left, t, pq, k);
-        if (pq.size() < k || (distr <= *pq.rbegin() + n->right->radius))
-          search(n->right, t, pq, k);
-
-      } else {
-        if (pq.size() < k || (distr <= *pq.rbegin() + n->right->radius))
-          search(n->right, t, pq, k);
-        if (pq.size() < k || (distl <= *pq.rbegin() + n->left->radius))
-          search(n->left, t, pq, k);
-      }
-    }
-  }
-};
diff --git a/algorithms/structure/bit2d.cpp b/algorithms/structure/bit2d.cpp
index 3158ab251ae707dfa79ed260c5bbd6f6b4d8e59d..fe8beb609b1ce593b6ed13792fd45bf5328ba6bd 100644
--- a/algorithms/structure/bit2d.cpp
+++ b/algorithms/structure/bit2d.cpp
@@ -11,7 +11,7 @@ struct BIT2D {
 
   BIT2D(int N, int M) :
     N(N), M(M), tree(N, vector<int>(M))
-  {}
+  { init(); }
 
   void init() {
     for (auto &i : tree)
diff --git a/algorithms/structure/bitmask.cpp b/algorithms/structure/bitmask.cpp
index bb118c7914c95989a7e61ade8dc5d4d792efb75d..59d2a928ef475f0e99b40694bfb1626102c77dad 100644
--- a/algorithms/structure/bitmask.cpp
+++ b/algorithms/structure/bitmask.cpp
@@ -7,8 +7,7 @@ struct Bitmask {
   ll state;
 
   Bitmask(ll state) :
-    state(state)
-  {}
+    state(state) {}
 
   void set(int pos) { 
     state |= (1 << pos); 
diff --git a/algorithms/structure/disjoint_set.cpp b/algorithms/structure/disjoint_set.cpp
index b40765aeb1cd66c1aae8553cd93e0673276f1c70..ad8de848fd81b870b7641510316a3c54a4aed654 100644
--- a/algorithms/structure/disjoint_set.cpp
+++ b/algorithms/structure/disjoint_set.cpp
@@ -12,14 +12,11 @@ struct DisjointSet {
 
   DisjointSet(int N) :
     N(N), rank(N), par(N)
-  {
-    for (int i = 0; i < N; ++i)
-      make_set(i);
-  }
+  { init(); }
 
-  void make_set(int x) {
-    par[x] = x;
-    rank[x] = 0;
+  void init() {
+    iota(all(par), 0);
+    fill(all(rank), 0);
   }
 
   int find_set(int x) {
@@ -33,12 +30,9 @@ struct DisjointSet {
     y = find_set(y);
 
     if (x != y) {
-      if (rank[x] > rank[y]) 
-        swap(x, y);
-
+      if (rank[x] > rank[y]) swap(x, y);
+      if (rank[x] == rank[y]) rank[x]++;
       par[x] = y;
-      if (rank[x] == rank[y]) 
-        rank[x]++;
     }
   }
 };
diff --git a/algorithms/structure/segment_tree.cpp b/algorithms/structure/segment_tree.cpp
index 2fe760dad6cdfad4e1cfd1100e131a8664c13565..3eb3784c5e233734d4c839f9baf6312ac723ae3f 100644
--- a/algorithms/structure/segment_tree.cpp
+++ b/algorithms/structure/segment_tree.cpp
@@ -10,8 +10,7 @@ struct SegmentTree {
   vector<int> tree;
 
   Tree(int N) : 
-    N(N), tree(2 * N, 0)
-  {}
+    N(N), tree(2 * N, 0) {}
 
   // Base depends on 'op':
   // op: a + b -> base: 0
diff --git a/caderno.pdf b/caderno.pdf
index 1cae42f8e9135fa0a3d6179c538151d700127988..dec18373d328149d7ddcb627daf79ae6b63ceb54 100644
Binary files a/caderno.pdf and b/caderno.pdf differ
diff --git a/contests/ICPC_LA16/H.cpp b/contests/ICPC_LA16/H.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ddc137896e1a1cad01ed1cf43e2966f2bfe3aa89
--- /dev/null
+++ b/contests/ICPC_LA16/H.cpp
@@ -0,0 +1,41 @@
+#include <bits/stdc++.h>
+
+#define EPS 1e-6
+#define MOD 1000000007
+#define inf 0x3f3f3f3f
+#define llinf 0x3f3f3f3f3f3f3f3f
+
+#define fi first
+#define se second
+#define pb push_back
+#define ende '\n'
+
+#define all(x) (x).begin(), (x).end()
+#define rall(x) (x).rbegin(), (x).rend()
+#define mset(x, y) memset(&x, (y), sizeof(x))
+
+using namespace std; 
+
+using ll = long long;
+using ii = pair<int,int>;
+
+int main() {
+  ios::sync_with_stdio(0);
+  cin.tie(0);
+
+  int n, k; cin >> n >> k;
+
+  int ans = 0;
+  multiset<int> S;
+  for (int i = 0; i < n; ++i) {
+    int x; cin >> x;
+    ans += x;
+    S.insert(x);
+    while (S.size() > (i + 1) / (k + 1)) 
+      S.erase(S.begin());
+  }
+
+  for (auto i : S) ans -= i;
+  cout << ans << ende;
+  return 0;
+}