From ef45f0c30a66e95ecd926543067fcd6c39db9f12 Mon Sep 17 00:00:00 2001
From: Bruno Freitas Tissei <bft15@inf.ufpr.br>
Date: Fri, 15 Feb 2019 00:15:13 -0200
Subject: [PATCH] Add Trie, problems, and change structure

Signed-off-by: Bruno Freitas Tissei <bft15@inf.ufpr.br>
---
 README.md                                     |   5 +-
 .../geometry}/convex_hull.cpp                 |   1 +
 .../graph}/articulations_bridges.cpp          |   5 +
 {graph => algorithms/graph}/bfs.cpp           |   0
 .../graph}/bipartite_match.cpp                |   0
 {graph => algorithms/graph}/dfs.cpp           |   0
 {graph => algorithms/graph}/dijkstra.cpp      |   0
 .../graph}/floyd_warshall.cpp                 |   0
 {graph => algorithms/graph}/kosaraju.cpp      |   0
 {graph => algorithms/graph}/kruskal.cpp       |   0
 {graph => algorithms/graph}/lca.cpp           |   0
 {graph => algorithms/graph}/tarjan.cpp        |   0
 .../graph}/topological_sort.cpp               |   0
 {math => algorithms/math}/fast_matrix_pow.cpp |   0
 .../math}/modular_multiplicative_inverse.cpp  |   0
 .../math}/sieve_of_eratosthenes.cpp           |   1 -
 .../paradigm}/edit_distance.cpp               |   0
 {paradigm => algorithms/paradigm}/kadane.cpp  |   0
 {paradigm => algorithms/paradigm}/lis.cpp     |   0
 .../paradigm}/ternary_search.cpp              |   0
 {string => algorithms/string}/kmp.cpp         |   0
 {structure => algorithms/structure}/avl.cpp   |   0
 .../structure}/ball_tree.cpp                  |   0
 {structure => algorithms/structure}/bit.cpp   |   0
 {structure => algorithms/structure}/bit2d.cpp |   0
 .../structure}/bitmask.cpp                    |   0
 .../structure}/disjoint_set.cpp               |   0
 .../structure}/lazy_segment_tree.cpp          |   0
 .../structure}/policy_tree.cpp                |   0
 .../structure}/segment_tree.cpp               |   0
 algorithms/structure/trie.cpp                 |  82 ++++++++++
 template.cpp => misc/template.cpp             |   1 -
 problems/crise_hidrica.cpp                    | 141 ++++++++++++++++++
 problems/escalacao.cpp                        | 107 +++++++++++++
 34 files changed, 339 insertions(+), 4 deletions(-)
 rename {geometry => algorithms/geometry}/convex_hull.cpp (99%)
 rename {graph => algorithms/graph}/articulations_bridges.cpp (91%)
 rename {graph => algorithms/graph}/bfs.cpp (100%)
 rename {graph => algorithms/graph}/bipartite_match.cpp (100%)
 rename {graph => algorithms/graph}/dfs.cpp (100%)
 rename {graph => algorithms/graph}/dijkstra.cpp (100%)
 rename {graph => algorithms/graph}/floyd_warshall.cpp (100%)
 rename {graph => algorithms/graph}/kosaraju.cpp (100%)
 rename {graph => algorithms/graph}/kruskal.cpp (100%)
 rename {graph => algorithms/graph}/lca.cpp (100%)
 rename {graph => algorithms/graph}/tarjan.cpp (100%)
 rename {graph => algorithms/graph}/topological_sort.cpp (100%)
 rename {math => algorithms/math}/fast_matrix_pow.cpp (100%)
 rename {math => algorithms/math}/modular_multiplicative_inverse.cpp (100%)
 rename {math => algorithms/math}/sieve_of_eratosthenes.cpp (99%)
 rename {paradigm => algorithms/paradigm}/edit_distance.cpp (100%)
 rename {paradigm => algorithms/paradigm}/kadane.cpp (100%)
 rename {paradigm => algorithms/paradigm}/lis.cpp (100%)
 rename {paradigm => algorithms/paradigm}/ternary_search.cpp (100%)
 rename {string => algorithms/string}/kmp.cpp (100%)
 rename {structure => algorithms/structure}/avl.cpp (100%)
 rename {structure => algorithms/structure}/ball_tree.cpp (100%)
 rename {structure => algorithms/structure}/bit.cpp (100%)
 rename {structure => algorithms/structure}/bit2d.cpp (100%)
 rename {structure => algorithms/structure}/bitmask.cpp (100%)
 rename {structure => algorithms/structure}/disjoint_set.cpp (100%)
 rename {structure => algorithms/structure}/lazy_segment_tree.cpp (100%)
 rename {structure => algorithms/structure}/policy_tree.cpp (100%)
 rename {structure => algorithms/structure}/segment_tree.cpp (100%)
 create mode 100644 algorithms/structure/trie.cpp
 rename template.cpp => misc/template.cpp (97%)
 create mode 100644 problems/crise_hidrica.cpp
 create mode 100644 problems/escalacao.cpp

diff --git a/README.md b/README.md
index bc5c447..06182a2 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
-# Implementações de algoritmos e resoluções de problemas; estudo, treino e consulta para programação competitiva (maratona de programação)
+# Implementações de algoritmos e resoluções de problemas
 
-Os algoritmos estão classificados por area de estudo e todos eles estão listados nas Issues.  
+Estudo, treino e consulta para programação competitiva (maratona de programação)  
+Os algoritmos estão classificados por categorias e todos eles estão listados nas Issues.  
diff --git a/geometry/convex_hull.cpp b/algorithms/geometry/convex_hull.cpp
similarity index 99%
rename from geometry/convex_hull.cpp
rename to algorithms/geometry/convex_hull.cpp
index e32b285..f1c1109 100644
--- a/geometry/convex_hull.cpp
+++ b/algorithms/geometry/convex_hull.cpp
@@ -7,6 +7,7 @@
 
 typedef pair<double,double> dd;
 
+
 // The three points are a counter-clockwise turn if cross > 0, clockwise if
 // cross < 0, and collinear if cross = 0
 double cross(dd a, dd b, dd c) {
diff --git a/graph/articulations_bridges.cpp b/algorithms/graph/articulations_bridges.cpp
similarity index 91%
rename from graph/articulations_bridges.cpp
rename to algorithms/graph/articulations_bridges.cpp
index 7d2d404..62b0868 100644
--- a/graph/articulations_bridges.cpp
+++ b/algorithms/graph/articulations_bridges.cpp
@@ -9,9 +9,14 @@ vector<int> graph[MAX];
 
 int cont[MAX], parent[MAX];
 int low[MAX], L[MAX];
+
+// Answer vector with bridges (edges)
 vector<ii> bridges;
+
+// Answer vector with articulations (vertices)
 vector<int> articulations;
 
+
 // Finds all articulations and bridges in the graph
 void dfs(int x) {
   int child = 0;
diff --git a/graph/bfs.cpp b/algorithms/graph/bfs.cpp
similarity index 100%
rename from graph/bfs.cpp
rename to algorithms/graph/bfs.cpp
diff --git a/graph/bipartite_match.cpp b/algorithms/graph/bipartite_match.cpp
similarity index 100%
rename from graph/bipartite_match.cpp
rename to algorithms/graph/bipartite_match.cpp
diff --git a/graph/dfs.cpp b/algorithms/graph/dfs.cpp
similarity index 100%
rename from graph/dfs.cpp
rename to algorithms/graph/dfs.cpp
diff --git a/graph/dijkstra.cpp b/algorithms/graph/dijkstra.cpp
similarity index 100%
rename from graph/dijkstra.cpp
rename to algorithms/graph/dijkstra.cpp
diff --git a/graph/floyd_warshall.cpp b/algorithms/graph/floyd_warshall.cpp
similarity index 100%
rename from graph/floyd_warshall.cpp
rename to algorithms/graph/floyd_warshall.cpp
diff --git a/graph/kosaraju.cpp b/algorithms/graph/kosaraju.cpp
similarity index 100%
rename from graph/kosaraju.cpp
rename to algorithms/graph/kosaraju.cpp
diff --git a/graph/kruskal.cpp b/algorithms/graph/kruskal.cpp
similarity index 100%
rename from graph/kruskal.cpp
rename to algorithms/graph/kruskal.cpp
diff --git a/graph/lca.cpp b/algorithms/graph/lca.cpp
similarity index 100%
rename from graph/lca.cpp
rename to algorithms/graph/lca.cpp
diff --git a/graph/tarjan.cpp b/algorithms/graph/tarjan.cpp
similarity index 100%
rename from graph/tarjan.cpp
rename to algorithms/graph/tarjan.cpp
diff --git a/graph/topological_sort.cpp b/algorithms/graph/topological_sort.cpp
similarity index 100%
rename from graph/topological_sort.cpp
rename to algorithms/graph/topological_sort.cpp
diff --git a/math/fast_matrix_pow.cpp b/algorithms/math/fast_matrix_pow.cpp
similarity index 100%
rename from math/fast_matrix_pow.cpp
rename to algorithms/math/fast_matrix_pow.cpp
diff --git a/math/modular_multiplicative_inverse.cpp b/algorithms/math/modular_multiplicative_inverse.cpp
similarity index 100%
rename from math/modular_multiplicative_inverse.cpp
rename to algorithms/math/modular_multiplicative_inverse.cpp
diff --git a/math/sieve_of_eratosthenes.cpp b/algorithms/math/sieve_of_eratosthenes.cpp
similarity index 99%
rename from math/sieve_of_eratosthenes.cpp
rename to algorithms/math/sieve_of_eratosthenes.cpp
index 6bf6c3e..dd30698 100644
--- a/math/sieve_of_eratosthenes.cpp
+++ b/algorithms/math/sieve_of_eratosthenes.cpp
@@ -5,7 +5,6 @@
  * Complexity (Space): O(n)
  */
 
-
 // Returns vector of primes less than or equal to n
 vector<int> sieve(int n) {
   vector<int> primes;
diff --git a/paradigm/edit_distance.cpp b/algorithms/paradigm/edit_distance.cpp
similarity index 100%
rename from paradigm/edit_distance.cpp
rename to algorithms/paradigm/edit_distance.cpp
diff --git a/paradigm/kadane.cpp b/algorithms/paradigm/kadane.cpp
similarity index 100%
rename from paradigm/kadane.cpp
rename to algorithms/paradigm/kadane.cpp
diff --git a/paradigm/lis.cpp b/algorithms/paradigm/lis.cpp
similarity index 100%
rename from paradigm/lis.cpp
rename to algorithms/paradigm/lis.cpp
diff --git a/paradigm/ternary_search.cpp b/algorithms/paradigm/ternary_search.cpp
similarity index 100%
rename from paradigm/ternary_search.cpp
rename to algorithms/paradigm/ternary_search.cpp
diff --git a/string/kmp.cpp b/algorithms/string/kmp.cpp
similarity index 100%
rename from string/kmp.cpp
rename to algorithms/string/kmp.cpp
diff --git a/structure/avl.cpp b/algorithms/structure/avl.cpp
similarity index 100%
rename from structure/avl.cpp
rename to algorithms/structure/avl.cpp
diff --git a/structure/ball_tree.cpp b/algorithms/structure/ball_tree.cpp
similarity index 100%
rename from structure/ball_tree.cpp
rename to algorithms/structure/ball_tree.cpp
diff --git a/structure/bit.cpp b/algorithms/structure/bit.cpp
similarity index 100%
rename from structure/bit.cpp
rename to algorithms/structure/bit.cpp
diff --git a/structure/bit2d.cpp b/algorithms/structure/bit2d.cpp
similarity index 100%
rename from structure/bit2d.cpp
rename to algorithms/structure/bit2d.cpp
diff --git a/structure/bitmask.cpp b/algorithms/structure/bitmask.cpp
similarity index 100%
rename from structure/bitmask.cpp
rename to algorithms/structure/bitmask.cpp
diff --git a/structure/disjoint_set.cpp b/algorithms/structure/disjoint_set.cpp
similarity index 100%
rename from structure/disjoint_set.cpp
rename to algorithms/structure/disjoint_set.cpp
diff --git a/structure/lazy_segment_tree.cpp b/algorithms/structure/lazy_segment_tree.cpp
similarity index 100%
rename from structure/lazy_segment_tree.cpp
rename to algorithms/structure/lazy_segment_tree.cpp
diff --git a/structure/policy_tree.cpp b/algorithms/structure/policy_tree.cpp
similarity index 100%
rename from structure/policy_tree.cpp
rename to algorithms/structure/policy_tree.cpp
diff --git a/structure/segment_tree.cpp b/algorithms/structure/segment_tree.cpp
similarity index 100%
rename from structure/segment_tree.cpp
rename to algorithms/structure/segment_tree.cpp
diff --git a/algorithms/structure/trie.cpp b/algorithms/structure/trie.cpp
new file mode 100644
index 0000000..b1bd70d
--- /dev/null
+++ b/algorithms/structure/trie.cpp
@@ -0,0 +1,82 @@
+/**
+ * Trie 
+ *
+ * Complexity (Time):
+ *   Insert -> O(m)
+ *   Search -> O(m)
+ * Complexity (Space): O(alphabet_size * N)
+ */
+
+// ========== Trie for String ==========
+int states = 0;
+int data[MAX][26];
+
+// ending[i] is true when the node i represents the last
+// character of a string contained in the Trie
+bool ending[MAX];
+
+// Insert word into the Trie
+void insert(string word) {
+  int node = 0;
+
+  for (int i = 0; i < word.size(); ++i) {
+    int b = word[i] - 'a';
+
+    if (data[node][b] == -1)
+      data[node][b] = states++;
+    node = data[node][b];
+  }
+
+  ending[node] = true;
+}
+
+// Return true if word is in the Trie 
+bool search(string word) {
+  int node = 0;
+
+  for (int i = 0; i < word.size(); ++i) {
+    node = data[node][word[i] - 'a'];
+    if (node == -1)
+      return false;
+  }
+
+  return ending[node];
+}
+
+
+// ========== Trie for Integer ==========
+int states = 0;
+int data[MAX][2];
+
+// ending[i] is true when the node i represents the last
+// bit of an integer contained in the Trie
+bool ending[MAX];
+
+// Insert x into the Trie
+void insert(int x) {
+  int node = 0;
+
+  for (int i = 0; i < 32; ++i) {
+    int b = x >> (31 - i) & 1;
+
+    if (data[node][b] == -1)
+      data[node][b] = states++;
+    node = data[node][b];
+  }
+
+  ending[node] = true;
+}
+
+// Return true if x is in the Trie 
+bool search(int x) {
+  int node = 0;
+  
+  for (int i = 0; i < 32; ++i) {
+    int b = x >> (31 - i) & 1;
+    node = data[node][b];
+    if (node == -1)
+      return false;
+  }
+
+  return ending[node];
+}
diff --git a/template.cpp b/misc/template.cpp
similarity index 97%
rename from template.cpp
rename to misc/template.cpp
index d7a0c74..fce5f0b 100644
--- a/template.cpp
+++ b/misc/template.cpp
@@ -1,6 +1,5 @@
 #include <bits/stdc++.h>
 
-#define MAX 0
 #define MOD 1000000007
 #define EPS 1e-6
 #define inf 0x3f3f3f3f
diff --git a/problems/crise_hidrica.cpp b/problems/crise_hidrica.cpp
new file mode 100644
index 0000000..1d06258
--- /dev/null
+++ b/problems/crise_hidrica.cpp
@@ -0,0 +1,141 @@
+#include <bits/stdc++.h>
+
+#define MAX 5010
+#define MAXLOG 20
+#define MOD 1000000007
+#define EPS 1e-6
+#define inf 0x3f3f3f3f
+#define llinf 0x3f3f3f3f3f3f3f3f
+
+#define fi first
+#define se second
+#define sz size()
+#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; 
+
+typedef long long ll;
+typedef pair<int,int> ii;
+
+int found;
+ll dp[MAX][1010];
+ll v[MAX];
+vector<int> graph[MAX];
+
+int h[MAX];
+int par[MAX][MAXLOG];
+ll upd[MAX];
+
+void dfs(int va, int p = -1) {
+  par[va][0] = p;
+
+  if (p + 1)
+    h[va] = h[p] + 1;
+
+  for (int i = 1; i < MAXLOG; ++i)
+    if (par[va][i - 1] + 1)
+      par[va][i] = par[par[va][i - 1]][i - 1];
+
+  for (auto u : graph[va]) 
+    if (p != u)
+      dfs(u, va);
+}
+
+
+void preprocess(int va) {
+  memset(par, -1, sizeof par);
+  dfs(va);
+}
+
+
+int query(int p, int q) {
+  if (h[p] < h[q])
+    swap(p, q);
+
+  for (int i = MAXLOG - 1; i >= 0; --i)
+    if (par[p][i] + 1 && h[par[p][i]] >= h[q]) {
+      p = par[p][i];
+    }
+
+  if (p == q)
+    return p;
+
+  for (int i = MAXLOG - 1; i >= 0; --i)
+    if (par[p][i] + 1 && par[p][i] != par[q][i]) {
+      p = par[p][i];
+      q = par[q][i];
+    }
+
+  return par[p][0];
+}
+
+
+ll fill(int x, int pare) {
+  ll ans = 0;
+
+  for (auto i : graph[x])
+    if (i != pare)
+      ans += fill(i, x);
+
+  return v[x] = ans + upd[x];
+}
+
+
+int main() {
+  ios::sync_with_stdio(0);
+  cin.tie(0);
+
+  int n, d, a, b;
+  cin >> n >> d;
+  for (int i = 0; i < n - 1; ++i) {
+    cin >> a >> b;
+    graph[a].pb(b);
+    graph[b].pb(a);
+  }
+
+  int m, vv, c;
+  cin >> m;
+  vector<int> w(m+1), avail;
+  for (int i = 0; i < m; ++i) {
+    cin >> c >> vv;
+    w[i+1] = vv;
+    avail.pb(c);
+  }
+
+  preprocess(1);
+
+  ll q, l;
+  int x, y;
+  cin >> q;
+  for (int i = 0; i < q; ++i) {
+    cin >> x >> y >> l;
+    int lca = query(x, y);
+
+    upd[lca] -= l;
+    upd[x] += l;
+    upd[y] += l;
+    if (lca != 1)
+      upd[par[lca][0]] -= l;
+  }
+
+  fill(1, -1);
+
+  vector<ll> vvv(m+1);
+  for (int i = 0; i < m; ++i)
+    vvv[i+1] = v[avail[i]];
+
+  for (int i = 1; i <= m; ++i)
+    for (int j = 0; j <= d; ++j)
+      if (j >= w[i])
+        dp[i][j] = max(dp[i-1][j], dp[i-1][j - w[i]] + vvv[i]);
+      else
+        dp[i][j] = dp[i-1][j];
+
+  cout << dp[m][d] << ende;
+  return 0;
+}
diff --git a/problems/escalacao.cpp b/problems/escalacao.cpp
new file mode 100644
index 0000000..f046333
--- /dev/null
+++ b/problems/escalacao.cpp
@@ -0,0 +1,107 @@
+#include <bits/stdc++.h>
+
+#define MAX 1010101
+#define MOD 1000000007
+#define EPS 1e-6
+#define inf 0x3f3f3f3f
+#define llinf 0x3f3f3f3f3f3f3f3f
+
+#define fi first
+#define se second
+#define sz size()
+#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; 
+
+typedef long long ll;
+typedef pair<int,int> ii;
+
+ll v[MAX];
+ll n, k, r;
+vector<ll> tree[MAX];
+vector<ll> res;
+
+void merge(vector<ll> a, vector<ll> b, vector<ll> &ans) {
+  int i = 0, j = 0, cnt = 0;
+  for ( ; cnt < k && i < a.size() && j < b.size(); ++cnt)
+    if (a[i] > b[j])
+      ans.push_back(a[i++]);
+    else
+      ans.push_back(b[j++]);
+
+  if (cnt < k) {
+    if (i < a.size())
+      for (; cnt < k && i < a.size(); ++i, ++cnt)
+        ans.push_back(a[i]);
+    else
+      for (; cnt < k && j < b.size(); ++j, ++cnt)
+        ans.push_back(b[j]);
+  }
+}
+
+
+void build(int node = 1, int a = 0, int b = n - 1) {
+  if (a > b)
+    return;
+  if (a == b) {
+    tree[node].push_back(v[a]);
+    return;
+  }
+
+  build(node * 2, a, (a + b) / 2);
+  build(node * 2 + 1, 1 + (a + b) / 2, b);
+  merge(tree[node * 2], tree[node * 2 + 1], tree[node]);
+}
+
+
+void query(int i, int j, int node = 1, int a = 0, int b = n - 1) {
+  if (a > b || a > j || b < i)
+    return;
+  if (a >= i && b <= j) {
+    res.insert(res.end(), tree[node].begin(), tree[node].end());
+    return;
+  }
+
+  query(i, j, node * 2, a, (a + b) / 2);
+  query(i, j, 1 + node * 2, 1 + (a + b) / 2, b);
+}
+
+
+int main() {
+  ios::sync_with_stdio(0);
+  cin.tie(0);
+
+  cin >> n >> k >> r;
+  for (int i = 0; i < n; ++i)
+    cin >> v[i];
+  build();
+
+  for (int i = 0; i < r; ++i) {
+    int ans = 1;
+    res.clear();
+    ll a, b; cin >> a >> b;
+    query(a - 1, b - 1);
+
+    sort(res.begin(), res.end());
+
+    int cnt = 0;
+    for (int j = res.size() - 1; j >= 0; --j) {
+      if (cnt >= k || res[j] == 0) {
+        if (res[j] == 0 && j == res.size() - 1)
+          ans = 0;
+        break;
+      }
+      ans = (ans * res[j]) % MOD;
+      cnt++;
+    }
+
+    cout << ans << ende;
+  }
+
+  return 0;
+}
-- 
GitLab