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 ¢er, vector<point> &ps) { + pair<double,int> get_radius(point ¢er, + 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 ¢er) { @@ -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