diff --git a/algorithms/graph/centroid_decomposition.cpp b/algorithms/graph/centroid_decomposition.cpp index 7cb5041607054ed0bbdde6894d67df1533c188dc..ba4d697c0f5f088cfa22630964e1ca7a3cff0c5a 100644 --- a/algorithms/graph/centroid_decomposition.cpp +++ b/algorithms/graph/centroid_decomposition.cpp @@ -1,15 +1,15 @@ /// Centroid Decomposition /// /// Description: -/// The Centroid Decomposition of a tree is a tree where its root is the -/// centroid of the original tree, and its children are the centroid of each +/// The Centroid Decomposition of a tree is a tree where: 1) its root is the +/// centroid of the original tree, and 2) its children are the centroid of each /// tree resulting from the removal of the root from the original tree. \par -/// The result is a tree with $lg(n)$ height, where the path from $a$ to $b$ -/// in the original tree can be decomposed into the path from a to lca($a$,$b$) +/// The result is a tree with $\log n$ height, where the path from $a$ to $b$, +/// in the original tree, can be decomposed into the path from a to lca($a$,$b$) /// and from lca($a$,$b$) to $b$. \par /// This is useful because each one of the $n^2$ paths of the original tree -/// is the concatenation of two paths in a set of $O(n lg(n))$ paths from a -/// node to all its ancestors in the centroid decomposition. +/// is a concatenation of two paths in a set of $O(n \log n)$ paths (from each +/// node to all of its ancestors in the centroid decomposition). /// /// Time: O(V log V) /// Space: O(V + E) diff --git a/algorithms/paradigm/edit_distance.cpp b/algorithms/paradigm/edit_distance.cpp index 71ff93cdef0506b4ce32b2a82645c2f216abedd2..1704de2736ad22ef8211292e0e1d0ccfed3169f6 100644 --- a/algorithms/paradigm/edit_distance.cpp +++ b/algorithms/paradigm/edit_distance.cpp @@ -3,12 +3,9 @@ /// Time: O(m * n) /// Space: O(m * n) -struct EditDistance { - vector<vector<int>> dp; - - EditDistance(int N, int M) : - dp(N, vector<int>(M)) {} +int dp[MAX][MAX]; +struct EditDistance { int run(string a, string b) { for (int i = 0; i <= a.size(); ++i) for (int j = 0; j <= b.size(); ++j) diff --git a/algorithms/paradigm/longest_common_subsequence.cpp b/algorithms/paradigm/longest_common_subsequence.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e324fb170fdf7d0dbb865ea175eea30e5ca18186 --- /dev/null +++ b/algorithms/paradigm/longest_common_subsequence.cpp @@ -0,0 +1,40 @@ +/// Longest Common Subsequence +/// +/// Time: O(n * m) +/// Space: O(n * m) + +int dp[MAX][MAX]; + +struct LCS { + string run(string a, string b) { + for (int i = 0; i <= a.size(); ++i) { + for (int j = 0; j <= b.size(); ++j) { + if (i == 0 || j == 0) + dp[i][j] = 0; + else if (a[i - 1] == b[j - 1]) + dp[i][j] = dp[i - 1][j - 1] + 1; + else + dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); + } + } + + // The size is already at dp[n][m], now the common + // subsequence is retrieved + + int idx = dp[a.size()][b.size()]; + string ans(idx, ' '); + + int i = a.size(), j = b.size(); + while (i > 0 && j > 0) { + if (a[i - 1] == b[ j - 1]) { + ans[idx - 1] = a[i - 1]; + i--, j--, idx--; + } else if (dp[i - 1][j] > dp[i][j - 1]) + i--; + else + j--; + } + + return ans; + } +}; diff --git a/algorithms/structure/sqrt_decomposition.cpp b/algorithms/structure/sqrt_decomposition.cpp index 69cfd43e7fd48768404251e550ab43ffb95faf9a..2defc34aa7ef7b0cfa44ceae21876f387b154104 100644 --- a/algorithms/structure/sqrt_decomposition.cpp +++ b/algorithms/structure/sqrt_decomposition.cpp @@ -2,7 +2,7 @@ /// /// Time: /// - preprocess: O(n) -/// - query: O(sqrt(n)) +/// - query: O(sqrt{n}) /// - update: O(1) /// Space: O(n) diff --git a/caderno.pdf b/caderno.pdf index 7fc0671ca628986b8ef7296abdaa30054a7e47e9..4b9d5207012eadeb183f0faa34051d31810dc47a 100644 Binary files a/caderno.pdf and b/caderno.pdf differ