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 ¢er, - 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 ¢er) { - 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; +}