diff --git a/algorithms/graph/centroid_decomposition.cpp b/algorithms/graph/centroid_decomposition.cpp
index 80a783d622e848d118b84447f81ada4f9c92310f..b6509c6c2bdf755e6fe7ebc3c0b3ded7b0f606ec 100644
--- a/algorithms/graph/centroid_decomposition.cpp
+++ b/algorithms/graph/centroid_decomposition.cpp
@@ -9,14 +9,18 @@ vector<int> graph[MAX];
 struct CentroidDecomposition {
   vector<int> par, size, marked;
 
+  /// Constructor.
+  /// @param N number of vertices
   CentroidDecomposition(int N) :
-    par(N), size(N), marked(N)
+    par(N), size(N), marked(N) 
   {
     init();
   }
 
   void init() {
     fill(all(marked), 0);
+
+    // Assuming vertices are 0-indexed
     build(0, -1);
   }
 
diff --git a/algorithms/paradigm/edit_distance.cpp b/algorithms/paradigm/edit_distance.cpp
index 57eddec5d6d5f3e69254dd6bf16af534aa715eab..2d9af1f9cf84a755813ab9fd462b7a45dc820a1a 100644
--- a/algorithms/paradigm/edit_distance.cpp
+++ b/algorithms/paradigm/edit_distance.cpp
@@ -3,28 +3,27 @@
 /// Complexity (Time): O(m*n) 
 /// Complexity (Space): O(m*n)
 
-int dp[MAX][MAX];
+struct EditDistance {
+  vector<vector<int>> dp;
 
-/// Returns edit distance (Levenshtein distance) between a and b
-/// @param a,b input strings
-int edit_distance(string a, string b) {
-  int n = a.size();
-  int m = b.size();
+  EditDistance(int N, int M) :
+    dp(N, vector<int>(M))
+  {}
 
-  for (int i = 0; i <= n; ++i) {
-    for (int j = 0; j <= m; ++j) {
-      if (i == 0)
-        dp[i][j] = j;
-      else if (j == 0)
-        dp[i][j] = i;
-      else if (a[i-1] == b[j-1])
-        dp[i][j] = d[i-1][j-1];
-      else
-        dp[i][j] = 1 + min({dp[i][j-1],     // Insert
-                            dp[i-1][j],     // Remove
-                            dp[i-1][j-1]}); // Replace
-    }
-  }
+  /// Returns edit distance (Levenshtein distance) between a and b
+  /// @param a,b input strings
+  int run(string a, string b) {
+    for (int i = 0; i <= a.size(); ++i)
+      for (int j = 0; j <= b.size(); ++j)
+        if (i == 0)
+          dp[i][j] = j;
+        else if (j == 0)
+          dp[i][j] = i;
+        else if (a[i-1] == b[j-1])
+          dp[i][j] = d[i-1][j-1];
+        else
+          dp[i][j] = 1 + min({dp[i][j-1], dp[i-1][j], dp[i-1][j-1]});
 
-  return dp[n][m];
-}
+    return dp[a.size()][b.size()];
+  }
+};
diff --git a/algorithms/paradigm/kadane.cpp b/algorithms/paradigm/kadane.cpp
index 5ce946d07edc3de78b46f1c1c80f7597e971d23d..b0fc99b9035e1194e0aa5f64301df0ae47c36d0d 100644
--- a/algorithms/paradigm/kadane.cpp
+++ b/algorithms/paradigm/kadane.cpp
@@ -3,35 +3,35 @@
 /// Complexity (Time): O(n + m)
 /// Complexity (Space): O(n + m)
 
-/// Returns the largest sum of a contiguous subarray
-/// @param[in] v input vector
-/// @param[out] start,end start and end index of said subarray
-int kadane(const vector<int> &v, int &start, int &end) {
+struct Kadane {
 
-  int n = v.size(), s = 0;
-  start = end = 0;
+  /// Returns the largest sum of a contiguous subarray
+  /// @param[in] v input vector
+  /// @param[out] start,end start and end index of said subarray
+  int run(const vector<int> &v, int &start, int &end) {
+    start = end = 0;
 
-  // Maximum so far (msf), Maximum ending here (meh).
-  int msf = -inf, meh = 0;
+    // Maximum so far (msf), Maximum ending here (meh).
+    int msf = -inf, meh = 0, s = 0;
 
-  for (int i = 0; i < n; ++i) {
-    meh += v[i];
+    for (int i = 0; i < v.size(); ++i) {
+      meh += v[i];
 
-    // Store maximum so far as well as starting and ending position
-    // of the subsequence
-    if (msf < meh) {
-      msf = meh;
-      start = s;
-      end = i;
-    }
+      // Store maximum so far as well as starting and ending position
+      // of the subsequence
+      if (msf < meh) {
+        msf = meh;
+        start = s, end = i;
+      }
 
-    // If maximum ending here is negative, then it's definitely 
-    // better to restart
-    if (meh < 0) {
-      meh = 0;
-      s = i + 1;
+      // If maximum ending here is negative, then it's definitely 
+      // better to restart
+      if (meh < 0) {
+        meh = 0;
+        s = i + 1;
+      }
     }
-  }
 
-  return msf;
-}
+    return msf;
+  }
+};
diff --git a/algorithms/paradigm/lis.cpp b/algorithms/paradigm/lis.cpp
index 8290e0640acff65ec3467ece711fa3c1c50e5093..f6150a40453d41c933f6ca3dc49ec10225d2a5f1 100644
--- a/algorithms/paradigm/lis.cpp
+++ b/algorithms/paradigm/lis.cpp
@@ -3,21 +3,21 @@
 /// Complexity (Time): O(n^2)
 /// Complexity (Space): O(n)
 
-/// Returns the length of the longest increasing subsequence
-/// @param v input vector 
-int lis(vector<int> v) {
-  int n = v.size();
+struct LIS {
 
-  vector<int> lis(n);
-  lis[0] = 1;
+  /// Returns the length of the longest increasing subsequence
+  /// @param v input vector 
+  int run(vector<int> v) {
+    vector<int> lis(v.size()); lis[0] = 1;
 
-  for (int i = 1; i < n; ++i) {
-    lis[i] = 1;
+    for (int i = 1; i < v.size(); ++i) {
+      lis[i] = 1;
 
-    for (int j = 0; j < i; ++j)
-      if (v[i] > v[j] && lis[i] < lis[j] + 1)
-        lis[i] = lis[j] + 1;
-  }
+      for (int j = 0; j < i; ++j)
+        if (v[i] > v[j] && lis[i] < lis[j] + 1)
+          lis[i] = lis[j] + 1;
+    }
 
-  return *max_element(all(lis));
-}
+    return *max_element(all(lis));
+  }
+};
diff --git a/algorithms/paradigm/ternary_search.cpp b/algorithms/paradigm/ternary_search.cpp
index b4254903c992fb96e1bf2ef283289f67e2789a3f..6e462ac52c7b11c26c1b3c1fe194e4d42e426a47 100644
--- a/algorithms/paradigm/ternary_search.cpp
+++ b/algorithms/paradigm/ternary_search.cpp
@@ -3,32 +3,34 @@
 /// Complexity (Time): O(log n)
 /// Complexity (Space): O(1)
 
-#define EPS 1e-6 
+struct TernarySearch {
+  const double EPS = 1e-6;
 
-/// Unimodal function 
-double f(double x) {
-  return x * x;
-}
+  /// Unimodal function 
+  double f(double x) {
+    return x * x;
+  }
 
-/// Executes ternary search to find maximum or minimum
-/// @param l,r boundaries of search 
-double ternary_search(double l, double r) {
-  double rt, lt;
+  /// Executes ternary search to find maximum or minimum
+  /// @param l,r boundaries of search 
+  double run(double l, double r) {
+    double rt, lt;
 
-  for (int i = 0; i < 500; ++i) {
-    if (fabs(r - l) < EPS)
-      return (l + r) / 2.0;
+    for (int i = 0; i < 500; ++i) {
+      if (fabs(r - l) < EPS)
+        return (l + r) / 2.0;
 
-    lt = (r - l) / 3.0 + l;
-    rt = ((r - l) * 2.0) / 3.0 + l;
+      lt = (r - l) / 3.0 + l;
+      rt = ((r - l) * 2.0) / 3.0 + l;
 
-    // < | minimum of f
-    // > | maximum of f
-    if (f(lt) < f(rt))
-      l = lt;
-    else
-      r = rt;
-  }
+      // < | minimum of f
+      // > | maximum of f
+      if (f(lt) < f(rt))
+        l = lt;
+      else
+        r = rt;
+    }
 
-  return (l + r) / 2.0;
-}
+    return (l + r) / 2.0;
+  }
+};
diff --git a/algorithms/structure/disjoint_set.cpp b/algorithms/structure/disjoint_set.cpp
index 16351316b071a58a5977898e28191d64572bec04..076ab7103889b36c25fb3e59ae9b2ce3e0bde611 100644
--- a/algorithms/structure/disjoint_set.cpp
+++ b/algorithms/structure/disjoint_set.cpp
@@ -10,9 +10,12 @@ struct DisjointSet {
   int N;
   vector<int> rank, par;
 
-  Disjoint(int N) :
+  DisjointSet(int N) :
     N(N), rank(N), par(N)
-  {}
+  {
+    for (int i = 0; i < N; ++i)
+      make_set(i);
+  }
 
   /// Initializes element x.
   void make_set(int x) {
diff --git a/algorithms/structure/trie.cpp b/algorithms/structure/trie.cpp
index 785bcff1e618e6269e38d330eb51f0a3bd785620..90f8c13253882baf2c886d1e13071a93b0861dee 100644
--- a/algorithms/structure/trie.cpp
+++ b/algorithms/structure/trie.cpp
@@ -19,7 +19,7 @@ struct Trie {
   { init(); }
 
   void init() {
-    state = 0;
+    states = 0;
     for (auto &i : trie)
       fill(all(i), -1);
   }
diff --git a/contests/CodeJam/2018/Round 2/A.cpp b/contests/CodeJam/2018/Round 2/A.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..86fd46cd04fe69d54a34b0f9099100e36dbe3e31
--- /dev/null
+++ b/contests/CodeJam/2018/Round 2/A.cpp	
@@ -0,0 +1,91 @@
+#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 t; cin >> t;
+  for (int cas = 1; cas <= t; ++cas) {
+    int c; cin >> c;
+    vector<int> v(c);
+
+    int grt = 0;
+    for (auto &i : v) {
+      cin >> i;
+      grt = max(grt, i);
+    }
+
+    cout << "Case #" << cas << ": ";
+    if (v[0] == 0 || v[c-1] == 0) {
+      cout << "IMPOSSIBLE" << ende;
+      continue;
+    }
+
+    vector<int> dest(c);
+    int l = 0, r = c - 1;
+    for (int i = 0; i < 1000; ++i) {
+      if (l >= r) break;
+      if (v[l] > 0) {
+        for (int i = 0; i < v[l]; ++i)
+          dest[l+i] = l;
+        l += v[l];
+      }
+
+      if (v[r] > 0) {
+        for (int i = 0; i < v[r]; ++i)
+          dest[r-i] = r;
+        r -= v[r];
+      }
+    }
+
+
+    vector<string> ans(grt, string(c, '.'));
+
+    vector<int> curr(c);
+    iota(all(curr), 0);
+    for (int i = 0; i < grt; ++i) {
+      for (int j = 0; j < c; ++j) {
+        if (curr[j] > dest[j]) {
+          ans[i][curr[j]] = '/';
+          curr[j]--;
+        } else if (curr[j] < dest[j]) {
+          ans[i][curr[j]] = '\\';
+          curr[j]++;
+        }
+      }
+    }
+
+    bool poss = true;
+    for (int i = 0; i < c; ++i)
+      if (curr[i] != dest[i])
+        poss = false;
+
+    if (poss) {
+      cout << grt << ende;
+      for (auto i : ans)
+        cout << i << ende;
+    } else
+      cout << "IMPOSSIBLE" << ende;
+  }
+
+  return 0;
+}
diff --git a/contests/CodeJam/2018/Round 2/a.out b/contests/CodeJam/2018/Round 2/a.out
new file mode 100755
index 0000000000000000000000000000000000000000..0151de957bf717487cacbff8a43e59fcc27cff15
Binary files /dev/null and b/contests/CodeJam/2018/Round 2/a.out differ