├── .gitignore ├── LICENSE ├── README.md ├── data_structures ├── bit.cpp ├── bit2d.cpp ├── bit_build.cpp ├── euler_tour_tree.cpp ├── li_chao.cpp ├── meldable_heap.cpp ├── merge_sort_tree.cpp ├── merge_sort_tree_upd.cpp ├── minqueue.cpp ├── minqueue_sum.cpp ├── mo.cpp ├── mo_hilbert.cpp ├── persistent_seg_dinamic.cpp ├── persistent_treap.cpp ├── seg.cpp ├── seg2d.cpp ├── seg_class.cpp ├── seg_iter.cpp ├── sparse_table.cpp ├── splay.cpp ├── sqrttree.cpp ├── treap.cpp ├── treap_build.cpp ├── treap_impl.cpp ├── trie.cpp ├── trie_xor.cpp ├── wavelet.cpp └── wavelet_static.cpp ├── dynamic_programming ├── divide_and_conquer.cpp ├── knapsack_01.cpp ├── knapsack_bitset.cpp ├── knapsack_bounded.cpp ├── knapsack_unbounded.cpp ├── lcs.cpp ├── lis.cpp └── subset_sums.cpp ├── etc ├── bitset_extra.cpp ├── compression.cpp ├── fast_input.cpp └── seed_random.cpp ├── geometry ├── convex_hull.cpp ├── point.cpp └── rectangle_union.cpp ├── graph ├── bfs.cpp ├── biconnected_component.cpp ├── bridge_articulation.cpp ├── centroid_decomposition.cpp ├── dfs.cpp ├── dijkstra.cpp ├── dinic.cpp ├── eulerian_path.cpp ├── hld.cpp ├── hungarian.cpp ├── kruskal.cpp ├── lca_binary_lifting.cpp ├── maximum_clique.cpp ├── strongly_connected.cpp └── union_find.cpp ├── math ├── bigint.cpp ├── binary_gcd.cpp ├── binary_perm.cpp ├── brent.cpp ├── carmichael.cpp ├── choose.cpp ├── compute_wheel.cpp ├── determinant.cpp ├── discrete_log.cpp ├── fast_ilog.cpp ├── fast_modcheck.cpp ├── fast_pollard_rho.cpp ├── gcdext.cpp ├── inv.cpp ├── inverse.cpp ├── linear_mobius.cpp ├── linear_phi.cpp ├── linear_sieve.cpp ├── linear_sieve_ext.cpp ├── matrix_expo.cpp ├── phi.cpp ├── pisano.cpp ├── pollard_rho.cpp ├── prime_count.cpp ├── rabin_miller.cpp ├── rabin_miller_bench.cpp ├── segmented_sieve.cpp ├── segmented_sieve_bit.cpp ├── sieve.cpp └── wheel_factorization.cpp └── string ├── aho_corasick.cpp ├── hash.cpp ├── manacher.cpp ├── prefix.cpp └── suffix_array.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore all 2 | * 3 | # Unignore all with extensions 4 | !*.* 5 | # Unignore all dirs 6 | !*/ 7 | !LICENSE 8 | *.txt 9 | gen.* -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | CC0 1.0 Universal 2 | 3 | Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an "owner") of an original work of 8 | authorship and/or a database (each, a "Work"). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific 12 | works ("Commons") that the public can reliably and without fear of later 13 | claims of infringement build upon, modify, incorporate in other works, reuse 14 | and redistribute as freely as possible in any form whatsoever and for any 15 | purposes, including without limitation commercial purposes. These owners may 16 | contribute to the Commons to promote the ideal of a free culture and the 17 | further production of creative, cultural and scientific works, or to gain 18 | reputation or greater distribution for their Work in part through the use and 19 | efforts of others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation 22 | of additional consideration or compensation, the person associating CC0 with a 23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 25 | and publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights ("Copyright and 31 | Related Rights"). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 34 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 35 | and translate a Work; 36 | 37 | ii. moral rights retained by the original author(s) and/or performer(s); 38 | 39 | iii. publicity and privacy rights pertaining to a person's image or likeness 40 | depicted in a Work; 41 | 42 | iv. rights protecting against unfair competition in regards to a Work, 43 | subject to the limitations in paragraph 4(a), below; 44 | 45 | v. rights protecting the extraction, dissemination, use and reuse of data in 46 | a Work; 47 | 48 | vi. database rights (such as those arising under Directive 96/9/EC of the 49 | European Parliament and of the Council of 11 March 1996 on the legal 50 | protection of databases, and under any national implementation thereof, 51 | including any amended or successor version of such directive); and 52 | 53 | vii. other similar, equivalent or corresponding rights throughout the world 54 | based on applicable law or treaty, and any national implementations thereof. 55 | 56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 59 | and Related Rights and associated claims and causes of action, whether now 60 | known or unknown (including existing as well as future claims and causes of 61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 62 | duration provided by applicable law or treaty (including future time 63 | extensions), (iii) in any current or future medium and for any number of 64 | copies, and (iv) for any purpose whatsoever, including without limitation 65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 66 | the Waiver for the benefit of each member of the public at large and to the 67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 68 | shall not be subject to revocation, rescission, cancellation, termination, or 69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 70 | by the public as contemplated by Affirmer's express Statement of Purpose. 71 | 72 | 3. Public License Fallback. Should any part of the Waiver for any reason be 73 | judged legally invalid or ineffective under applicable law, then the Waiver 74 | shall be preserved to the maximum extent permitted taking into account 75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 76 | is so judged Affirmer hereby grants to each affected person a royalty-free, 77 | non transferable, non sublicensable, non exclusive, irrevocable and 78 | unconditional license to exercise Affirmer's Copyright and Related Rights in 79 | the Work (i) in all territories worldwide, (ii) for the maximum duration 80 | provided by applicable law or treaty (including future time extensions), (iii) 81 | in any current or future medium and for any number of copies, and (iv) for any 82 | purpose whatsoever, including without limitation commercial, advertising or 83 | promotional purposes (the "License"). The License shall be deemed effective as 84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 85 | License for any reason be judged legally invalid or ineffective under 86 | applicable law, such partial invalidity or ineffectiveness shall not 87 | invalidate the remainder of the License, and in such case Affirmer hereby 88 | affirms that he or she will not (i) exercise any of his or her remaining 89 | Copyright and Related Rights in the Work or (ii) assert any associated claims 90 | and causes of action with respect to the Work, in either case contrary to 91 | Affirmer's express Statement of Purpose. 92 | 93 | 4. Limitations and Disclaimers. 94 | 95 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 96 | surrendered, licensed or otherwise affected by this document. 97 | 98 | b. Affirmer offers the Work as-is and makes no representations or warranties 99 | of any kind concerning the Work, express, implied, statutory or otherwise, 100 | including without limitation warranties of title, merchantability, fitness 101 | for a particular purpose, non infringement, or the absence of latent or 102 | other defects, accuracy, or the present or absence of errors, whether or not 103 | discoverable, all to the greatest extent permissible under applicable law. 104 | 105 | c. Affirmer disclaims responsibility for clearing rights of other persons 106 | that may apply to the Work or any use thereof, including without limitation 107 | any person's Copyright and Related Rights in the Work. Further, Affirmer 108 | disclaims responsibility for obtaining any necessary consents, permissions 109 | or other rights required for any use of the Work. 110 | 111 | d. Affirmer understands and acknowledges that Creative Commons is not a 112 | party to this document and has no duty or obligation with respect to this 113 | CC0 or use of the Work. 114 | 115 | For more information, please see 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # algorithm-implementations 2 | Competitive programming algorithms implementations in C++ 3 | -------------------------------------------------------------------------------- /data_structures/bit.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // const int maxn = 1010101; 6 | 7 | template 8 | struct bit 9 | { 10 | T v[maxn]; 11 | 12 | void add(int x, const T& d) 13 | { 14 | for (int i = x; i < maxn; i += i&-i) 15 | v[i] += d; 16 | } 17 | 18 | T get(int x) 19 | { 20 | T ans{}; 21 | for (int i = x; i > 0; i -= i&-i) 22 | ans += v[i]; 23 | return ans; 24 | } 25 | }; 26 | 27 | bit b; 28 | 29 | int main() 30 | { 31 | 32 | } -------------------------------------------------------------------------------- /data_structures/bit2d.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | template 6 | struct Bit2d 7 | { 8 | T b[size][size]; 9 | 10 | void add(int x, int y, T d) 11 | { 12 | for (int i = x; i < size; i += i&-i) { 13 | for (int j = y; j < size; j += j&-j) 14 | b[i][j] += d; 15 | } 16 | } 17 | 18 | T get(int x, int y) 19 | { 20 | T ans = 0; 21 | for (int i = x; i; i -= i&-i) { 22 | for (int j = y; j; j -= j&-j) { 23 | ans += b[i][j]; 24 | } 25 | } 26 | } 27 | }; 28 | 29 | int main() 30 | { 31 | 32 | } -------------------------------------------------------------------------------- /data_structures/bit_build.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | template 6 | struct Bit 7 | { 8 | int b[size]; 9 | 10 | void add(int x, int d) 11 | { 12 | for (int i = x; i < size; i += i&-i) 13 | b[i] += d; 14 | } 15 | 16 | int get(int x) 17 | { 18 | int ans = 0; 19 | for (int i = x; i; i -= i&-i) 20 | ans += b[i]; 21 | return ans; 22 | } 23 | 24 | void build(int* v, int n) 25 | { 26 | for (int i = 1; i <= n; i++) { 27 | b[i] += v[i]; 28 | if (i + (i&-i) < size) 29 | b[i + (i&-i)] += b[i]; 30 | } 31 | } 32 | 33 | void linearize(int *v, int n) 34 | { 35 | for (int i = n; i >= 1; i--) { 36 | if (i + (i&-i) < size) 37 | b[i + (i&-i)] -= b[i]; 38 | } 39 | for (int i = 1; i <= n; i++ ) 40 | v[i] = b[i]; 41 | } 42 | }; 43 | 44 | const int maxn = 101010; 45 | 46 | int v[maxn]; 47 | Bit bit; 48 | 49 | int main() 50 | { 51 | int n; 52 | cin >> n; 53 | 54 | for (int i = 1; i <= n; i++) 55 | cin >> v[i]; 56 | 57 | bit.build(v, n); 58 | 59 | int q; 60 | cin >> q; 61 | 62 | while (q--) { 63 | int op; 64 | cin >> op; 65 | 66 | // update 67 | if (op == 1) { 68 | int pos, val; 69 | cin >> pos >> val; 70 | 71 | bit.add(pos, val-v[pos]); 72 | v[pos] = val; 73 | } 74 | // query 75 | else { 76 | int x; 77 | cin >> x; 78 | 79 | cout << bit.get(x) << "\n"; 80 | } 81 | } 82 | 83 | bit.linearize(v, n); 84 | for (int i = 1; i <= n; i++) 85 | cout << v[i] << " "; 86 | cout << "\n"; 87 | } -------------------------------------------------------------------------------- /data_structures/euler_tour_tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ff first 4 | #define ss second 5 | 6 | #define pb push_back 7 | #define eb emplace_back 8 | #define all(x) begin(x), end(x) 9 | #define rall(x) rbegin(x), rend(x) 10 | #define clr(x, c) memset((x), (c), sizeof((x))) 11 | 12 | using namespace std; 13 | 14 | template void DBG(T&& x) { cerr << x << " "; } 15 | template void DBG(T&& x, Args&&... args) { DBG(x); DBG(args...); } 16 | #define DBG(...) cerr << "[" << #__VA_ARGS__ << "]: "; DBG(__VA_ARGS__); cerr << endl 17 | 18 | 19 | using ll = long long; 20 | using ii = pair; 21 | 22 | int const inf = 0x3f3f3f3f; 23 | ll const linf = 0x3f3f3f3f3f3f3f3f; 24 | 25 | int const mod = 1e9 + 7; 26 | 27 | seed_seq seq { 28 | (uint64_t) chrono::duration_cast( 29 | chrono::high_resolution_clock::now(). 30 | time_since_epoch()).count(), 31 | (uint64_t) __builtin_ia32_rdtsc(), 32 | (uint64_t) random_device{}(), 33 | (uint64_t) 17 34 | }; 35 | 36 | mt19937 rd{seq}; 37 | 38 | namespace Treap { 39 | struct Node 40 | { 41 | int v; 42 | int h, sz = 1; 43 | ll cheese = 0, sauce = 0; 44 | ll sum_cheese = 0, sum_sauce = 0; 45 | ll lazy_sauce = 0; 46 | Node *l = nullptr, *r = nullptr, *pai = nullptr; 47 | 48 | Node(int x) 49 | : v(x), h(rd()) {}; 50 | }; 51 | 52 | using treap = Node*; 53 | 54 | int sz(treap t) { 55 | return t? t->sz : 0; 56 | } 57 | 58 | void push(treap t) { 59 | if (!t) return; 60 | t->sauce += t->lazy_sauce; 61 | t->sum_sauce += t->lazy_sauce * sz(t); 62 | if (t->l) t->l->lazy_sauce += t->lazy_sauce; 63 | if (t->r) t->r->lazy_sauce += t->lazy_sauce; 64 | t->lazy_sauce = 0; 65 | } 66 | 67 | void reset(treap t) { 68 | if (!t) return; 69 | t->sum_sauce = t->sauce; 70 | t->sum_cheese = t->cheese; 71 | } 72 | 73 | void op(treap t) { 74 | if (!t) return; 75 | t->sz = 1 + sz(t->l) + sz(t->r); 76 | 77 | reset(t); 78 | push(t->l); 79 | push(t->r); 80 | 81 | if (t->l) { 82 | t->l->pai = t; 83 | t->sum_cheese += t->l->sum_cheese; 84 | t->sum_sauce += t->l->sum_sauce; 85 | } 86 | 87 | if (t->r) { 88 | t->r->pai = t; 89 | t->sum_cheese += t->r->sum_cheese; 90 | t->sum_sauce += t->r->sum_sauce; 91 | } 92 | } 93 | 94 | void merge(treap &t, treap l, treap r) { 95 | push(l), push(r); op(l), op(r); 96 | if (!l or !r) 97 | (t=l?l:r); 98 | else if (l->h > r->h) 99 | merge(l->r, l->r, r), t = l; 100 | else 101 | merge(r->l, l, r->l), t = r; 102 | op(t); 103 | } 104 | 105 | void split(treap t, treap &l, treap &r, int pos) { 106 | push(t); op(t); 107 | if (!t) return void(l=r=nullptr); 108 | int p = sz(t->l) + 1; 109 | 110 | if (pos > p) 111 | split(t->r, t->r, r, pos - p), l = t; 112 | else 113 | split(t->l, l, t->l, pos), r = t; 114 | 115 | op(l), op(r); 116 | } 117 | 118 | int pos(treap t) { 119 | if (!t) return 0; 120 | if (!t->pai) return sz(t->l) + 1; 121 | return (t == t->pai->r? sz(t->l) + 1 : -sz(t->r)-1) + pos(t->pai); 122 | } 123 | } 124 | 125 | using namespace Treap; 126 | 127 | int const maxn = 303030; 128 | 129 | int n; 130 | vector g[maxn]; 131 | treap t = nullptr; 132 | vector v[maxn]; 133 | int gin[maxn]; 134 | treap ed[maxn][2]; 135 | 136 | namespace ET { 137 | void dfs(int u) { 138 | auto tu = new Node(u); 139 | ed[u][0] = tu; 140 | merge(t, t, tu); 141 | 142 | for (int v : g[u]) dfs(v); 143 | 144 | tu = new Node(u); 145 | ed[u][1] = tu; 146 | merge(t, t, tu); 147 | } 148 | 149 | void create() { 150 | for (int i = 1; i <= n; i++) { 151 | if (gin[i] == 0) { 152 | dfs(i); 153 | } 154 | } 155 | t->pai = nullptr; 156 | } 157 | 158 | treap get_subtree(int u, bool include = true) { 159 | int pos_u[2] = {pos(ed[u][0]) - include + 1, pos(ed[u][1]) + include}; 160 | 161 | treap lu = nullptr, ru = nullptr; 162 | split(t, t, ru, pos_u[1]); 163 | split(t, lu, t, pos_u[0]); 164 | 165 | treap aux = t; 166 | 167 | merge(t, lu, ru); 168 | 169 | if (t) t->pai = nullptr; 170 | if (aux) aux->pai = nullptr; 171 | 172 | return aux; 173 | } 174 | 175 | tuple get_subtrees(int u) { 176 | int pos_u[2] = {pos(ed[u][0]), pos(ed[u][1]) + 1}; 177 | 178 | treap lu = nullptr, ru = nullptr; 179 | split(t, t, ru, pos_u[1]); 180 | split(t, lu, t, pos_u[0]); 181 | 182 | if (t) t->pai = nullptr; 183 | if (lu) lu->pai = nullptr; 184 | if (ru) ru->pai = nullptr; 185 | 186 | return {lu, t, ru}; 187 | } 188 | 189 | void merge_subtrees(treap l, treap sub, treap r) { 190 | merge(t, l, sub); 191 | merge(t, t, r); 192 | t->pai = nullptr; 193 | } 194 | 195 | void insert_subtree(int u, treap v) { 196 | int pos_u[2] = {pos(ed[u][0]) + 1, pos(ed[u][1])}; 197 | 198 | treap aux = nullptr; 199 | 200 | split(t, t, aux, pos_u[0]); 201 | 202 | merge(t, t, v); 203 | merge(t, t, aux); 204 | 205 | t->pai = nullptr; 206 | } 207 | 208 | bool inside_subtree(int u, int v) { 209 | int pos_u[2] = {pos(ed[u][0]), pos(ed[u][1])}; 210 | int pos_v = pos(ed[v][0]); 211 | 212 | return pos_u[0] <= pos_v and pos_v <= pos_u[1]; 213 | } 214 | } 215 | 216 | int main() { 217 | ios_base::sync_with_stdio(false), cin.tie(nullptr); 218 | 219 | int m, q; 220 | 221 | cin >> n >> m >> q; 222 | 223 | for (int i = 0; i < m; i++) { 224 | int u, v; 225 | cin >> u >> v; 226 | 227 | gin[v]++; 228 | g[u].pb(v); 229 | } 230 | 231 | ET::create(); 232 | 233 | while (q--) { 234 | string op; 235 | cin >> op; 236 | 237 | if (op == "swap") { 238 | int u, v; 239 | cin >> u >> v; 240 | 241 | if (ET::inside_subtree(u, v) or ET::inside_subtree(v, u)) { 242 | continue; 243 | } 244 | 245 | auto sub_u = ET::get_subtree(u, false); 246 | auto sub_v = ET::get_subtree(v, false); 247 | 248 | ET::insert_subtree(u, sub_v); 249 | ET::insert_subtree(v, sub_u); 250 | } 251 | else if (op == "append") { 252 | int u, v; 253 | cin >> u >> v; 254 | 255 | if (ET::inside_subtree(v, u)) { 256 | continue; 257 | } 258 | 259 | auto sub_v = ET::get_subtree(v); 260 | 261 | ET::insert_subtree(u, sub_v); 262 | } 263 | else if (op == "sauce") { 264 | int u, y; 265 | cin >> u >> y; 266 | 267 | auto [lu, sub_u, ru] = ET::get_subtrees(u); 268 | 269 | sub_u->lazy_sauce += y; 270 | push(sub_u); 271 | 272 | ET::merge_subtrees(lu, sub_u, ru); 273 | 274 | } 275 | else if (op == "cheese") { 276 | int u, y; 277 | cin >> u >> y; 278 | 279 | auto [lu, sub_u, ru] = ET::get_subtrees(u); 280 | treap t = nullptr; 281 | 282 | int p = pos(ed[u][1]); 283 | split(sub_u, sub_u, t, p); 284 | t->cheese += y; 285 | merge(sub_u, sub_u, t); 286 | sub_u->pai = nullptr; 287 | 288 | split(sub_u, t, sub_u, 2); 289 | t->cheese += y; 290 | merge(sub_u, t, sub_u); 291 | sub_u->pai = nullptr; 292 | 293 | ET::merge_subtrees(lu, sub_u, ru); 294 | } 295 | else if (op == "querySauce") { 296 | int u; 297 | cin >> u; 298 | 299 | auto [lu, sub_u, ru] = ET::get_subtrees(u); 300 | cout << sub_u->sum_sauce / 2 << '\n'; 301 | 302 | ET::merge_subtrees(lu, sub_u, ru); 303 | } 304 | else if (op == "queryCheese") { 305 | int u; 306 | cin >> u; 307 | 308 | auto [lu, sub_u, ru] = ET::get_subtrees(u); 309 | cout << sub_u->sum_cheese / 2 << '\n'; 310 | 311 | ET::merge_subtrees(lu, sub_u, ru); 312 | } 313 | } 314 | } 315 | -------------------------------------------------------------------------------- /data_structures/li_chao.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | using ll = long long; 6 | 7 | int const maxn = 101010; 8 | ll const inf = 0x3f3f3f3; 9 | 10 | template> 11 | struct LiChao { 12 | private: 13 | struct Fc { 14 | ll a, b; 15 | 16 | ll eval(ll x) { 17 | return a*x + b; 18 | } 19 | }; 20 | 21 | struct Node { 22 | Fc fn; 23 | unique_ptr l, r; 24 | 25 | Node(Fc fn) : fn(fn) {} 26 | }; 27 | 28 | unique_ptr root; 29 | 30 | void upd(unique_ptr &t, ll l, ll r, Fc fn, Op op = Op{}) { 31 | ll m = (l+r)/2; 32 | 33 | bool bleft = op(fn.eval(l), t->fn.eval(l)); 34 | bool bmid = op(fn.eval(m), t->fn.eval(m)); 35 | 36 | if (bmid) swap(t->fn, fn); 37 | if (l >= r) return; 38 | 39 | if (bleft != bmid) { 40 | if (!t->l) t->l = make_unique(fn); 41 | else upd(t->l, l, m, fn); 42 | } 43 | else { 44 | if (!t->r) t->r = make_unique(fn); 45 | else upd(t->r, m+1, r, fn); 46 | } 47 | } 48 | 49 | 50 | ll get(unique_ptr &t, ll x, ll l, ll r) { 51 | ll m = (l+r)/2; 52 | if (l == r and l == x) return t->fn.eval(x); 53 | 54 | if (x <= m and t->l) 55 | return min(t->fn.eval(x), get(t->l, x, l, m)); 56 | else if (x > m and t->r) 57 | return min(t->fn.eval(x), get(t->r, x, m+1, r)); 58 | 59 | return t->fn.eval(x); 60 | } 61 | public: 62 | LiChao() : root(nullptr) {} 63 | 64 | void upd(ll a, ll b, ll l = 0, ll r = 1e6) { 65 | if (!root) { 66 | root = make_unique(Fc{a, b}); 67 | return; 68 | } 69 | upd(root, l, r, {a, b}); 70 | } 71 | 72 | ll get(ll x, ll l = 0, ll r = 1e6) { 73 | return get(root, x, l, r); 74 | } 75 | }; 76 | ll a[maxn], b[maxn], dp[maxn]; 77 | 78 | int main() 79 | { 80 | ios::sync_with_stdio(false), cin.tie(nullptr); 81 | 82 | int n; 83 | cin >> n; 84 | 85 | for (int i = 1; i <= n; i++) cin >> a[i]; 86 | for (int i = 1; i <= n; i++) cin >> b[i]; 87 | 88 | LiChao<> l; 89 | 90 | l.upd(b[1], 0); 91 | 92 | dp[1] = b[1]; 93 | 94 | for (int i = 2; i <= n; i++) { 95 | dp[i] = l.get(a[i]); 96 | l.upd(b[i], dp[i]); 97 | } 98 | 99 | cout << dp[n] << "\n"; 100 | } -------------------------------------------------------------------------------- /data_structures/meldable_heap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct node 6 | { 7 | int val; 8 | 9 | node *l, *r; 10 | 11 | node(int val) 12 | : val(val), l(nullptr), r(nullptr) {}; 13 | }; 14 | 15 | mt19937 rd; 16 | uniform_int_distribution toss(0, 1); 17 | 18 | node* meld(node *&l, node *&r) 19 | { 20 | if (!l) return r; 21 | if (!r) return l; 22 | 23 | if (l->val > r->val) swap(l, r); 24 | 25 | if (toss(rd)) l->l = meld(l->l, r); 26 | else l->r = meld(l->r, r); 27 | 28 | return l; 29 | } 30 | 31 | void insert(node *&t, int x) 32 | { 33 | node *aux = new node(x); 34 | 35 | t = meld(t, aux); 36 | } 37 | 38 | void pop(node *&t) 39 | { 40 | if (!t) return; 41 | 42 | t = meld(t->l, t->r); 43 | } 44 | 45 | int min(node *t) 46 | { 47 | return t? t->val: 0; 48 | } 49 | 50 | node *t = nullptr; 51 | 52 | int main() 53 | { 54 | insert(t, 2); 55 | insert(t, 3); 56 | insert(t, 4); 57 | print(t); 58 | cout << "\n"; 59 | cout << min(t) << "\n"; 60 | pop(t); 61 | cout << min(t) << "\n"; 62 | } -------------------------------------------------------------------------------- /data_structures/merge_sort_tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LEFT ((no<<1)+1) 4 | #define RIGHT ((no<<1)+2) 5 | 6 | using namespace std; 7 | 8 | template 9 | struct mtree 10 | { 11 | vector tree[maxn*4]; 12 | T* v; 13 | 14 | mtree() = default; 15 | mtree(T* vv) : v(vv) {}; 16 | 17 | void build(int no, int l, int r) 18 | { 19 | if (l == r) return void(tree[no].push_back(v[l])); 20 | 21 | int m = (l+r)>>1; 22 | 23 | build(LEFT, l, m); 24 | build(RIGHT, m+1, r); 25 | 26 | merge(tree[LEFT].begin(), tree[LEFT].end(), 27 | tree[RIGHT].begin(), tree[RIGHT].end(), 28 | back_inserter(tree[no])); 29 | } 30 | 31 | inline int f(int no, int x, int y) 32 | { 33 | return upper_bound(tree[no].begin(), tree[no].end(), y) - 34 | lower_bound(tree[no].begin(), tree[no].end(), x); 35 | } 36 | 37 | int get(int no, int l, int r, int a, int b, int x, int y) 38 | { 39 | if (a <= l and r <= b) return f(no, x, y); 40 | 41 | int m = (l+r)>>1; 42 | 43 | if (b <= m) return get(LEFT, l, m, a, b, x, y); 44 | if (a > m) return get(RIGHT, m+1, r, a, b, x, y); 45 | 46 | return get(LEFT, l, m, a, b, x, y) + 47 | get(RIGHT, m+1, r, a, b, x, y); 48 | } 49 | }; 50 | 51 | int main() 52 | { 53 | } -------------------------------------------------------------------------------- /data_structures/merge_sort_tree_upd.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LEFT ((no<<1)+1) 4 | #define RIGHT ((no<<1)+2) 5 | 6 | using namespace std; 7 | 8 | template 9 | struct treap 10 | { 11 | struct node 12 | { 13 | T val; 14 | int h, sz; 15 | node *l, *r; 16 | 17 | node(T v) 18 | : val(v), h(rand()), sz(1), l(nullptr), r(nullptr) {}; 19 | }; 20 | 21 | node *root; 22 | 23 | treap() : root(nullptr) {}; 24 | 25 | int sz(node* t) 26 | { 27 | return t? t->sz : 0; 28 | } 29 | 30 | void op(node* t) 31 | { 32 | if (!t) return; 33 | 34 | t->sz = sz(t->l) + 1 + sz(t->r); 35 | } 36 | 37 | void merge(node *&t, node *l, node *r) 38 | { 39 | if (!l or !r) return void(t = l? l : r); 40 | 41 | if (l->h > r->h) merge(l->r, l->r, r), t = l; 42 | else merge(r->l, l, r->l), t = r; 43 | 44 | op(t); 45 | } 46 | 47 | void split(node *t, node *&l, node *&r, T val) 48 | { 49 | if (!t) return void(l = r = nullptr); 50 | 51 | if (val <= t->val) split(t->l, l, t->l, val), r = t; 52 | else split(t->r, t->r, r, val), l = t; 53 | 54 | op(l), op(r); 55 | } 56 | 57 | void insert(node *&t, node *v) 58 | { 59 | if (!t) return void(t = v); 60 | 61 | if (v->h > t->h) split(t, v->l, v->r, v->val), t = v; 62 | else if (v->val <= t->val) insert(t->l, v); 63 | else insert(t->r, v); 64 | 65 | op(t); 66 | } 67 | 68 | void erase(node *&t, T v) 69 | { 70 | if (!t) return; 71 | 72 | if (t->val == v) { 73 | node *tmp = t; 74 | merge(t, t->l, t->r); 75 | delete tmp; 76 | } 77 | else if (t->val > v) erase(t->l, v); 78 | else erase(t->r, v); 79 | 80 | op(t); 81 | } 82 | 83 | void insert(T val) 84 | { 85 | node *v = new node(val); 86 | insert(root, v); 87 | } 88 | 89 | void erase(T val) 90 | { 91 | erase(root, val); 92 | } 93 | 94 | int size() 95 | { 96 | return sz(root); 97 | } 98 | 99 | int cnt(T x, T y) 100 | { 101 | node *l = nullptr, *r = nullptr; 102 | 103 | split(root, l, root, x); 104 | split(root, root, r, y); 105 | 106 | int ans = sz(root); 107 | 108 | merge(root, l, root); 109 | merge(root, root, r); 110 | 111 | return ans; 112 | } 113 | }; 114 | 115 | ostream& operator<<(ostream& out, const treap::node *t) 116 | { 117 | if (!t) return out; 118 | 119 | if (t->l) out << t->l; 120 | out << t->val << " "; 121 | if (t->r) out << t->r; 122 | return out; 123 | } 124 | 125 | ostream& operator<<(ostream& out, const treap& tp) 126 | { 127 | out << tp.root; 128 | 129 | return out; 130 | } 131 | 132 | template 133 | struct mtree 134 | { 135 | treap tree[maxn*3]{}; 136 | T *v; 137 | 138 | mtree() = default; 139 | 140 | mtree(T *vv) : v(vv) {}; 141 | 142 | void build(int no, int l, int r) 143 | { 144 | if (l == r) return void(tree[no].insert(v[l])); 145 | 146 | for (int i = l; i <= r; i++) tree[no].insert(v[i]); 147 | 148 | int m = (l+r)>>1; 149 | 150 | build(LEFT, l, m); 151 | build(RIGHT, m+1, r); 152 | } 153 | 154 | void upd(int no, int l, int r, int pos, T val) 155 | { 156 | tree[no].erase(v[pos]); 157 | tree[no].insert(val); 158 | 159 | if (l == r) return void(v[pos] = val); 160 | 161 | int m = (l+r)>>1; 162 | 163 | if (pos <= m) upd(LEFT, l, m, pos, val); 164 | else upd(RIGHT, m+1, r, pos, val); 165 | } 166 | 167 | // no of ocurrences of numbers of values [x,y) in [a,b] 168 | int get(int no, int l, int r, int a, int b, T x, T y) 169 | { 170 | if (a <= l and r <= b) return tree[no].cnt(x, y); 171 | 172 | int m = (l+r)>>1; 173 | 174 | if (b <= m) return get(LEFT, l, m, a, b, x, y); 175 | if (a > m) return get(RIGHT, m+1, r, a, b, x, y); 176 | 177 | return get(LEFT, l, m, a, b, x, y) + 178 | get(RIGHT, m+1, r, a, b, x, y); 179 | } 180 | 181 | void print(int no, int l, int r) 182 | { 183 | cout << tree[no] << "\n"; 184 | 185 | int m = (l+r)>>1; 186 | 187 | if (l == r) return; 188 | 189 | print(LEFT, l, m); 190 | print(RIGHT, m+1, r); 191 | } 192 | }; 193 | 194 | const int maxn = 101; 195 | 196 | int v[maxn]; 197 | mtree t{v}; 198 | 199 | int main() 200 | { 201 | int n; 202 | cin >> n; 203 | 204 | for (int i = 1; i <= n; i++) 205 | cin >> v[i]; 206 | 207 | t.build(0, 1, n); 208 | t.print(0, 1, n); 209 | } -------------------------------------------------------------------------------- /data_structures/minqueue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ff first 4 | #define ss second 5 | 6 | using namespace std; 7 | 8 | typedef pair ii; 9 | 10 | const int inf = 0x3f3f3f3f; 11 | 12 | struct minqueue 13 | { 14 | deque dq; 15 | 16 | int l, r; 17 | 18 | minqueue() { 19 | 20 | l = 1; 21 | r = 1; 22 | } 23 | 24 | void add(int x) 25 | { 26 | while(dq.size() >= 1 and dq.back().ff >= x) dq.pop_back(); 27 | 28 | dq.push_back({x, r++}); 29 | } 30 | 31 | void pop() 32 | { 33 | if (dq.front().ss == l++) dq.pop_front(); 34 | } 35 | 36 | int get() 37 | { 38 | return dq.empty()? inf: dq[0].ff; 39 | } 40 | }; 41 | 42 | int main() 43 | { 44 | return 0; 45 | } -------------------------------------------------------------------------------- /data_structures/minqueue_sum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ff first 4 | #define ss second 5 | 6 | using namespace std; 7 | 8 | typedef pair ii; 9 | 10 | struct minqueue 11 | { 12 | deque dq; 13 | 14 | int l, r, sum; 15 | 16 | void clear() 17 | { 18 | l = r = sum = 0; 19 | dq.clear(); 20 | } 21 | 22 | void push(int x) 23 | { 24 | while (!dq.empty() and dq.back().ff > x-sum) dq.pop_back(); 25 | dq.push_back({x-sum,r}); 26 | r++; 27 | } 28 | 29 | void pop() 30 | { 31 | if (!dq.empty() and dq.front().ss == l) dq.pop_front(); 32 | l++; 33 | } 34 | 35 | void add(int x) {sum += x;} 36 | 37 | int getmin() {return dq[0].ff+sum;} 38 | 39 | int size() {return r-l;} 40 | }; 41 | 42 | const int maxn = 1000; 43 | const int maxm = 100000; 44 | const int inf = 0x3f3f3f; 45 | 46 | minqueue q[maxm]; 47 | 48 | int d[maxm]; 49 | int w[maxn], e[maxn], c[maxn]; 50 | 51 | int main() 52 | { 53 | int n, m; 54 | cin >> n >> m; 55 | 56 | for (int i = 1; i <= n; i++) cin >> w[i] >> e[i] >> c[i]; 57 | 58 | for (int i = 1; i <= m; i++) d[i] = inf; 59 | 60 | for (int i = 1; i <= n; i++) { 61 | 62 | for (int j = 0; j < w[i]; j++) q[j].clear(); 63 | 64 | for (int j = 0; j <= m; j++) { 65 | 66 | minqueue& mq = q[j%w[i]]; 67 | 68 | if (mq.size() > e[i]) mq.pop(); 69 | 70 | mq.add(c[i]); 71 | mq.push(d[j]); 72 | 73 | d[j] = mq.getmin(); 74 | } 75 | } 76 | 77 | for (int i = 0; i <= m; i++) cout << d[i] << " "; 78 | cout << "\n"; 79 | } -------------------------------------------------------------------------------- /data_structures/mo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int maxn = 101010; 6 | const int maxq = 101010; 7 | 8 | struct Query 9 | { 10 | int l, bk, r, id; 11 | 12 | bool operator<(Query const& rhs) { 13 | if (bk == rhs.bk) { 14 | if (bk&1) return r > rhs.r; 15 | else return r < rhs.r; 16 | } 17 | return bk < rhs.bk; 18 | } 19 | }; 20 | 21 | int ans; 22 | int v[maxn], res[maxn]; 23 | Query qr[maxq]; 24 | 25 | void add(int x) 26 | { 27 | 28 | } 29 | 30 | void rem(int x) 31 | { 32 | 33 | } 34 | 35 | int main() 36 | { 37 | int n, q; 38 | cin >> n >> q; 39 | 40 | int sqt = sqrt(n)+1; 41 | 42 | for (int i = 0; i < n; i++) 43 | cin >> v[i]; 44 | 45 | for (int i = 0; i < q; i++) 46 | cin >> qr[i].l >> qr[i].r, qr[i].bk = qr[i].l/sqt, qr[i].id = i; 47 | 48 | sort(qr, qr+q); 49 | 50 | int cl = 0, cr = -1; 51 | for (int i = 0; i < q; i++) { 52 | int l = qr[i].l, r = qr[i].r; 53 | 54 | while (cr < r) add(++cr); 55 | while (cl > l) add(--cl); 56 | while (cr > r) rem(cr--); 57 | while (cl < l) rem(cl++); 58 | 59 | res[qr[i].id] = ans; 60 | } 61 | 62 | for (int i = 0; i < q; i++) 63 | cout << res[i] << "\n"; 64 | } -------------------------------------------------------------------------------- /data_structures/mo_hilbert.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | 7 | const int maxn = 100010; 8 | const int sqt = 330; 9 | 10 | inline int64_t ord(int x, int y, int pow, int rotate) { 11 | if (pow == 0) { 12 | return 0; 13 | } 14 | int hpow = 1 << (pow-1); 15 | int seg = (x < hpow) ? ( 16 | (y < hpow) ? 0 : 3 17 | ) : ( 18 | (y < hpow) ? 1 : 2 19 | ); 20 | seg = (seg + rotate) & 3; 21 | const int rotateDelta[4] = {3, 0, 0, 1}; 22 | int nx = x & (x ^ hpow), ny = y & (y ^ hpow); 23 | int nrot = (rotate + rotateDelta[seg]) & 3; 24 | int64_t subSquareSize = int64_t(1) << (2*pow - 2); 25 | int64_t ans = seg * subSquareSize; 26 | int64_t add = ord(nx, ny, pow-1, nrot); 27 | ans += (seg == 1 || seg == 2) ? add : (subSquareSize - add - 1); 28 | return ans; 29 | } 30 | 31 | struct query 32 | { 33 | int l, r, id; 34 | ll w; 35 | 36 | bool operator<(const query &rhs) const { 37 | return w < rhs.w; 38 | } 39 | }; 40 | 41 | int lim = 0; 42 | 43 | struct bit 44 | { 45 | int b[maxn]; 46 | 47 | inline void add(int x, int d) 48 | { 49 | for (int i = x; i <= lim; i += i&-i) b[i] += d; 50 | } 51 | 52 | inline int get(int x) 53 | { 54 | int ans = 0; 55 | for (int i = x; i > 0; i -= i&-i) ans += b[i]; 56 | return ans; 57 | } 58 | }; 59 | 60 | bit re; 61 | query qr[maxn]; 62 | int v[maxn], v2[maxn]; 63 | 64 | ll tot = 0; 65 | ll sum = 0; 66 | 67 | inline void addl(int x) 68 | { 69 | tot++; 70 | re.add(v[x], 1); 71 | sum += re.get(v[x]-1); 72 | } 73 | 74 | inline void addr(int x) 75 | { 76 | tot++; 77 | re.add(v[x], 1); 78 | sum += tot - re.get(v[x]); 79 | } 80 | 81 | inline void reml(int x) 82 | { 83 | tot--; 84 | re.add(v[x], -1); 85 | sum -= re.get(v[x]-1); 86 | } 87 | 88 | inline void remr(int x) 89 | { 90 | tot--; 91 | re.add(v[x], -1); 92 | sum -= tot - re.get(v[x]); 93 | } 94 | 95 | ll res[maxn]; 96 | 97 | 98 | 99 | inline int readChar(); 100 | template inline T readInt(); 101 | template inline void writeInt( T x, char end = 0 ); 102 | inline void writeChar( int x ); 103 | inline void writeWord( const char *s ); 104 | 105 | /** Read */ 106 | 107 | static const int buf_size = 4096; 108 | 109 | inline int getChar() { 110 | static char buf[buf_size]; 111 | static int len = 0, pos = 0; 112 | if (pos == len) 113 | pos = 0, len = fread(buf, 1, buf_size, stdin); 114 | if (pos == len) 115 | return -1; 116 | return buf[pos++]; 117 | } 118 | 119 | inline int readChar() { 120 | int c = getChar(); 121 | while (c <= 32) 122 | c = getChar(); 123 | return c; 124 | } 125 | 126 | template 127 | inline T readInt() { 128 | char c = readChar(); 129 | T x = 0; 130 | while ('0' <= c && c <= '9') 131 | x = x * 10 + c - '0', c = getChar(); 132 | return x; 133 | } 134 | 135 | /** Write */ 136 | 137 | static int write_pos = 0; 138 | static char write_buf[buf_size]; 139 | 140 | inline void writeChar( int x ) { 141 | if (write_pos == buf_size) 142 | fwrite(write_buf, 1, buf_size, stdout), write_pos = 0; 143 | write_buf[write_pos++] = x; 144 | } 145 | 146 | template 147 | inline void writeInt( T x, char end ) { 148 | if (x < 0) 149 | writeChar('-'), x = -x; 150 | 151 | char s[24]; 152 | int n = 0; 153 | while (x || !n) 154 | s[n++] = '0' + x % 10, x /= 10; 155 | while (n--) 156 | writeChar(s[n]); 157 | if (end) 158 | writeChar(end); 159 | } 160 | 161 | inline void writeWord( const char *s ) { 162 | while (*s) 163 | writeChar(*s++); 164 | } 165 | 166 | struct Flusher { 167 | ~Flusher() { 168 | if (write_pos) 169 | fwrite(write_buf, 1, write_pos, stdout), write_pos = 0; 170 | } 171 | } flusher; 172 | 173 | 174 | 175 | int main() 176 | { 177 | int n; 178 | n = readInt(); 179 | 180 | ll nn = 0; 181 | while ((1< cr) addr(++cr); 219 | while (r < cr) remr(cr--); 220 | while (l < cl) addl(--cl); 221 | while (l > cl) reml(cl++); 222 | 223 | res[id] = sum; 224 | } 225 | 226 | for (int i = 0; i < q; i++) writeInt(res[i],'\n'); 227 | 228 | return 0; 229 | } -------------------------------------------------------------------------------- /data_structures/persistent_seg_dinamic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ff first 4 | #define ss second 5 | #define MID ((l+r)/2) 6 | 7 | using namespace std; 8 | 9 | typedef pair ii; 10 | 11 | const int maxn = 100010; 12 | 13 | struct node 14 | { 15 | int sum; 16 | 17 | node *l, *r; 18 | 19 | node() { 20 | 21 | l = r = nullptr; 22 | 23 | sum = 0; 24 | } 25 | }; 26 | 27 | typedef node* pnode; 28 | 29 | int n; 30 | ii v[maxn]; 31 | int v2[maxn]; 32 | pnode root[maxn]; 33 | 34 | int sum(pnode t) 35 | { 36 | return t? t->sum: 0; 37 | } 38 | 39 | pnode build(int l, int r) 40 | { 41 | pnode cur = new node(); 42 | 43 | if (l == r) return cur; 44 | 45 | cur->l = build(l, MID); 46 | cur->r = build(MID+1, r); 47 | 48 | return cur; 49 | } 50 | 51 | pnode update(pnode idx, int l, int r, int pos, int val) 52 | { 53 | pnode cur = new node(); 54 | 55 | cur->sum = idx->sum; 56 | cur->l = idx->l; 57 | cur->r = idx->r; 58 | 59 | if (l == r) { 60 | 61 | cur->sum = val; 62 | return cur; 63 | } 64 | 65 | if (pos <= MID) cur->l = update(cur->l, l, MID, pos, val); 66 | else cur->r = update(cur->r, MID+1, r, pos, val); 67 | 68 | cur->sum = sum(cur->l) + sum(cur->r); 69 | 70 | return cur; 71 | } 72 | 73 | int query(pnode idx, int l, int r, int a, int b) 74 | { 75 | if (a <= l and b >= r) return sum(idx); 76 | 77 | if (l > b or r < a) return 0; 78 | 79 | int lchild = query(idx->l, l, MID, a, b); 80 | int rchild = query(idx->r, MID+1, r, a, b); 81 | 82 | return lchild+rchild; 83 | } 84 | 85 | int get(int a, int b, int k) 86 | { 87 | int l = 1, r = n, idx; 88 | 89 | while (l != r) { 90 | 91 | idx = (l+r)/2; 92 | 93 | int num = query(root[idx], 1, n, a, b); 94 | 95 | // cout << l << " " << idx << " " << r << " " << num << "\n"; 96 | 97 | if (num < k) l = idx+1; 98 | else r = idx; 99 | } 100 | 101 | idx = (l+r)/2; 102 | 103 | return idx; 104 | } 105 | 106 | int c[maxn]; 107 | 108 | int main() 109 | { 110 | cin >> n; 111 | 112 | for (int i = 1; i <= n; i++) cin >> v[i].ff, v[i].ss = i, v2[i] = v[i].ff; 113 | 114 | map mp; 115 | 116 | sort(v2+1, v2+n+1); 117 | 118 | int id = 1; 119 | 120 | for (int i = 1; i <= n; i++) { 121 | 122 | if (mp[v2[i]] == 0) mp[v2[i]] = id, c[id++] = v2[i]; 123 | } 124 | 125 | for (int i = 1; i <= n; i++) v[i].ff = mp[v[i].ff]; 126 | 127 | sort(v+1, v+n+1); 128 | 129 | root[0] = build(1, n); 130 | 131 | for (int i = 1; i <= n; i++) { 132 | 133 | root[i] = update(root[i-1], 1, n, v[i].ss, 1); 134 | } 135 | 136 | int q; 137 | cin >> q; 138 | 139 | while(q--) { 140 | 141 | int l, r, k; 142 | cin >> l >> r >> k; 143 | 144 | // int ans = query(root[k], 1, n, l, r); 145 | 146 | // cout << "\n"; 147 | int ans = get(l, r, k); 148 | // cout << "\n"; 149 | 150 | // cout << ans << "\n"; 151 | cout << c[ans] << "\n"; 152 | } 153 | 154 | return 0; 155 | } -------------------------------------------------------------------------------- /data_structures/persistent_treap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int maxn = 101010; 6 | 7 | template 8 | class Treap { 9 | private: 10 | struct Node 11 | { 12 | Node *l, *r; 13 | int h, sz; 14 | T val; 15 | bool old; 16 | 17 | Node(T const& val) 18 | : l(nullptr), r(nullptr), h(rand()), sz(1), val(val), old(false) {}; 19 | 20 | Node(Node* t) 21 | { 22 | *this = *t; 23 | old = true; 24 | } 25 | }; 26 | 27 | Node *root; 28 | 29 | int sz(Node *t) 30 | { 31 | return t? t->sz : 0; 32 | } 33 | 34 | void op(Node *t) 35 | { 36 | if (!t) return; 37 | 38 | t->sz = sz(t->l) + sz(t->r) + 1; 39 | } 40 | 41 | void clone(Node *t) 42 | { 43 | if (!t) return; 44 | 45 | if (t->old == false) return; 46 | 47 | if (t->l) t->l = new Node(t->l); 48 | if (t->r) t->r = new Node(t->r); 49 | 50 | t->old = true; 51 | } 52 | 53 | void merge(Node *&t, Node *l, Node *r) 54 | { 55 | clone(l), clone(r); 56 | 57 | if (!l or !r) return void (t = l? l: r); 58 | 59 | if (l->h > r->h) merge(l->r, l->r, r), t = l; 60 | else merge(r->l, l, r->l), t = r; 61 | 62 | op(t); 63 | } 64 | 65 | void split(Node *t, Node *&l, Node *&r, T val) 66 | { 67 | clone(t); 68 | 69 | if (!t) return void(l = r = nullptr); 70 | 71 | if (t->val < val) split(t->r, t->r, r, val), l = t; 72 | else split(t->l, l, t->l, val), r = t; 73 | 74 | op(l), op(r); 75 | } 76 | 77 | void insert(Node *&t, Node *v) 78 | { 79 | clone(t); 80 | 81 | if (!t) t = v; 82 | else if (v->h > t->h) 83 | split(t, v->l, v->r, v->val), t = v; 84 | else if (t->val < v->val) insert(t->r, v); 85 | else insert(t->l, v); 86 | 87 | op(t); 88 | } 89 | 90 | void erase(Node *&t, T v) 91 | { 92 | clone(t); 93 | 94 | if (!t) return; 95 | if (t->val == v) { 96 | Node *tmp = t; 97 | merge(t, t->l, t->r); 98 | delete tmp; 99 | } 100 | else if (t->val < v) erase(t->r, v); 101 | else erase(t->l, v); 102 | 103 | op(t); 104 | } 105 | 106 | T const& kth(Node *t, int k) 107 | { 108 | int pos = sz(t->l) + 1; 109 | 110 | if (k == pos) return t->val; 111 | else if (pos > k) return kth(t->l, k); 112 | else return kth(t->r, k-pos); 113 | } 114 | 115 | public: 116 | Treap() : root(nullptr) {} ; 117 | 118 | ~Treap() = default; 119 | // n sei o que fazer :/ 120 | 121 | Treap(Treap const& tp) : root(new Node(tp.root)) {}; 122 | 123 | Treap(Treap&& tp) : root(tp.root) {}; 124 | 125 | Treap& operator=(Treap const& tp) { 126 | root = new Node(tp.root); 127 | return *this; 128 | } 129 | 130 | Treap& operator=(Treap&& tp) { 131 | root = tp.root; 132 | return *this; 133 | } 134 | 135 | void insert(T const& v) 136 | { 137 | Node *t = new Node(v); 138 | insert(root, t); 139 | } 140 | 141 | void erase(T const& v) 142 | { 143 | erase(root, v); 144 | } 145 | 146 | T const& kth(int k) 147 | { 148 | return kth(root, k+1); 149 | } 150 | }; 151 | 152 | Treap v[maxn]; 153 | 154 | int main() 155 | { 156 | v[0].insert(4); 157 | 158 | v[1] = v[0]; 159 | v[1].insert(6); 160 | 161 | v[2] = v[1]; 162 | v[2].erase(4); 163 | 164 | cout << v[0].kth(0) << "\n"; 165 | cout << v[1].kth(0) << " " << v[1].kth(1) << "\n"; 166 | cout << v[2].kth(0) << "\n"; 167 | } -------------------------------------------------------------------------------- /data_structures/seg.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LEFT ((no<<1)+1) 4 | #define RIGHT ((no<<1)+2) 5 | 6 | using namespace std; 7 | 8 | const int maxn = 101010; 9 | 10 | template 11 | struct seg 12 | { 13 | T tree[maxn*3]; 14 | T *v; 15 | 16 | seg() = default; 17 | 18 | seg(T* vv) : v(vv) {}; 19 | 20 | T op(T a, T b) 21 | { 22 | return min(a, b); 23 | } 24 | 25 | void build(int no, int l, int r) 26 | { 27 | if (l == r) return void(tree[no] = v[l]); 28 | 29 | int m = (l+r)>>1; 30 | 31 | build(LEFT, l, m); 32 | build(RIGHT, m+1, r); 33 | 34 | tree[no] = op(tree[LEFT], tree[RIGHT]); 35 | } 36 | 37 | T get(int no, int l, int r, int a, int b) 38 | { 39 | if (a <= l and r <= b) return tree[no]; 40 | 41 | int m = (l+r)>>1; 42 | 43 | if (b <= m) return get(LEFT, l, m, a, b); 44 | if (a > m) return get(RIGHT, m+1, r, a, b); 45 | 46 | return op(get(LEFT, l, m, a, b), 47 | get(RIGHT, m+1, r, a, b)); 48 | } 49 | 50 | void upd(int no, int l, int r, int p, T val) 51 | { 52 | if (l == r) return void(tree[no] = val); 53 | 54 | int m = (l+r)>>1; 55 | 56 | if (p <= m) upd(LEFT, l, m, p, val); 57 | else upd(RIGHT, m+1, r, p, val); 58 | 59 | tree[no] = op(tree[LEFT], tree[RIGHT]); 60 | } 61 | }; 62 | 63 | int v[maxn]; 64 | seg s[10]; 65 | 66 | int main() 67 | { 68 | } 69 | 70 | -------------------------------------------------------------------------------- /data_structures/seg2d.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int const maxn = 1001; 6 | 7 | int n, m; 8 | int v[maxn][maxn]; 9 | 10 | int op(int x, int y) 11 | { 12 | return gcd(x, y); 13 | } 14 | 15 | class Seg 16 | { 17 | int tree[1<<11][1<<11]; 18 | 19 | void build_y(int nox, int noy, int lx, int rx, int ly, int ry) 20 | { 21 | if (ly == ry) { 22 | if (lx == rx) tree[nox][noy] = v[lx][ly]; 23 | else tree[nox][noy] = op(tree[nox*2+1][noy], tree[nox*2+2][noy]); 24 | } 25 | else { 26 | int my = (ly+ry)/2; 27 | build_y(nox, noy*2+1, lx, rx, ly, my); 28 | build_y(nox, noy*2+2, lx, rx, my+1, ry); 29 | tree[nox][noy] = op(tree[nox][noy*2+1], tree[nox][noy*2+2]); 30 | } 31 | } 32 | 33 | void build_x(int nox, int lx, int rx) 34 | { 35 | if (lx != rx) { 36 | int mx = (lx+rx)/2; 37 | build_x(nox*2+1, lx, mx); 38 | build_x(nox*2+2, mx+1, rx); 39 | } 40 | build_y(nox, 0, lx, rx, 1, m); 41 | } 42 | 43 | int get_y(int nox, int noy, int ly, int ry, int a, int b) 44 | { 45 | if (a <= ly and ry <= b) return tree[nox][noy]; 46 | 47 | int my = (ly+ry)/2; 48 | 49 | if (b <= my) return get_y(nox, noy*2+1, ly, my, a, b); 50 | if (a > my) return get_y(nox, noy*2+2, my+1, ry, a, b); 51 | 52 | return op(get_y(nox, noy*2+1, ly, my, a, b), 53 | get_y(nox, noy*2+2, my+1, ry, a, b)); 54 | } 55 | 56 | int get_x(int nox, int lx, int rx, int a, int b, int ay, int by) 57 | { 58 | if (a <= lx and rx <= b) return get_y(nox, 0, 1, m, ay, by); 59 | 60 | int mx = (lx+rx)/2; 61 | 62 | if (b <= mx) return get_x(nox*2+1, lx, mx, a, b, ay, by); 63 | if (a > mx) return get_x(nox*2+2, mx+1, rx, a, b, ay, by); 64 | 65 | return op(get_x(nox*2+1, lx, mx, a, b, ay, by), 66 | get_x(nox*2+2, mx+1, rx, a, b, ay, by)); 67 | } 68 | 69 | void upd_y(int nox, int noy, int lx, int rx, int ly, int ry, 70 | int x, int y, int val) 71 | { 72 | if (ly == ry) { 73 | if (lx == rx) tree[nox][noy] = val; 74 | else tree[nox][noy] = op(tree[nox*2+1][noy], tree[nox*2+2][noy]); 75 | } 76 | else { 77 | int my = (ly+ry)/2; 78 | if (y <= my) upd_y(nox, noy*2+1, lx, rx, ly, my, x, y, val); 79 | else upd_y(nox, noy*2+2, lx, rx, my+1, ry, x, y, val); 80 | tree[nox][noy] = op(tree[nox][noy*2+1], tree[nox][noy*2+2]); 81 | } 82 | } 83 | 84 | void upd_x(int nox, int lx, int rx, int x, int y, int val) 85 | { 86 | if (lx != rx) { 87 | int mx = (lx+rx)/2; 88 | if (x <= mx) upd_x(nox*2+1, lx, mx, x, y, val); 89 | else upd_x(nox*2+2, mx+1, rx, x, y, val); 90 | } 91 | upd_y(nox, 0, lx, rx, 1, m, x, y, val); 92 | } 93 | 94 | public: 95 | void build() 96 | { 97 | build_x(0, 1, n); 98 | } 99 | 100 | void upd(int x, int y, int val) 101 | { 102 | upd_x(0, 1, n, x, y, val); 103 | } 104 | 105 | int get(int lx, int rx, int ly, int ry) 106 | { 107 | return get_x(0, 1, n, lx, rx, ly, ry); 108 | } 109 | }; 110 | 111 | int main() 112 | { 113 | 114 | } -------------------------------------------------------------------------------- /data_structures/seg_class.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | class Seg { 5 | private: 6 | using join_t = std::function; 7 | using fix_t = std::function; 8 | 9 | int n; 10 | join_t const join; 11 | fix_t const fix = [] (T& a, T const& b) { a = b;}; 12 | 13 | std::vector tree; 14 | 15 | template 16 | T const& build(int no, int l, int r, Iter const& v) 17 | { 18 | if (l == r) 19 | return tree[no] = v[l]; 20 | 21 | int m = (l+r)/2; 22 | 23 | build(no*2+1, l, m, v); 24 | build(no*2+2, m+1, r, v); 25 | 26 | tree[no] = join(build(no*2+1, l, m, v), 27 | build(no*2+2, m+1, r, v)); 28 | 29 | return tree[no]; 30 | } 31 | 32 | void upd(int no, int l, int r, int pos, T val) 33 | { 34 | if (l == r) { 35 | fix(tree[no], val); 36 | return; 37 | } 38 | 39 | int m = (l+r)/2; 40 | 41 | if (pos <= m) upd(no*2+1, l, m, pos, val); 42 | else upd(no*2+2, m+1, r, pos, val); 43 | 44 | tree[no] = join(tree[no*2+1], tree[no*2+2]); 45 | } 46 | 47 | T get(int no, int l, int r, int a, int b) 48 | { 49 | if (a <= l and r <= b) return tree[no]; 50 | 51 | int m = (l+r)/2; 52 | 53 | if (b <= m) return get(no*2+1, l, m, a, b); 54 | if (a > m) return get(no*2+2, m+1, r, a, b); 55 | 56 | return join(get(no*2+1, l, m, a, b), 57 | get(no*2+2, m+1, r, a, b)); 58 | } 59 | 60 | public: 61 | Seg(int n_, join_t op_) : 62 | join(op_), n(n_), tree(n*4) {}; 63 | 64 | Seg(int n_, join_t op_, fix_t fix_) : 65 | join(op_), n(n_), fix(fix_), tree(n*4) {}; 66 | 67 | Seg(std::vector const& v, join_t op_) : 68 | join(op_), n(v.size()), tree(v.size()*4) 69 | { 70 | build(0, 0, n-1, v.data()); 71 | } 72 | 73 | Seg(std::vector const& v, join_t op_, fix_t fix_) : 74 | join(op_), n(v.size()), fix(fix_), tree(v.size()*4) 75 | { 76 | build(0, 0, n-1, v.data()); 77 | } 78 | 79 | template 80 | Seg(Iter const& begin, Iter const& end, join_t op_) : 81 | join(op_), n(end-begin), tree(4*(end-begin)) 82 | { 83 | build(0, 0, n-1, begin); 84 | } 85 | 86 | template 87 | Seg(Iter const& begin, Iter const& end, join_t op_, fix_t fix_) : 88 | join(op_), n(end-begin), fix(fix_), tree(4*(end-begin)) 89 | { 90 | build(0, 0, n-1, begin); 91 | } 92 | 93 | void upd(int pos, T val) 94 | { 95 | upd(0, 0, n-1, pos, val); 96 | } 97 | 98 | T get(int l, int r) 99 | { 100 | return get(0, 0, n-1, l, r); 101 | } 102 | }; 103 | 104 | // example (Baldes - OBI2018) 105 | namespace Problem 106 | { 107 | struct Node 108 | { 109 | int mini, maxi, ans; 110 | }; 111 | 112 | Node join(Node const& a, Node const& b) 113 | { 114 | Node ans; 115 | ans.mini = std::min(a.mini, b.mini); 116 | ans.maxi = std::max(a.maxi, b.maxi); 117 | ans.ans = std::max({a.ans, b.ans, 118 | abs(a.maxi-b.mini), 119 | abs(b.maxi-a.mini)}); 120 | return ans; 121 | } 122 | 123 | void fix(Node& a, Node const& b) 124 | { 125 | a.mini = std::min(a.mini, b.mini); 126 | a.maxi = std::max(a.maxi, b.maxi); 127 | } 128 | } 129 | 130 | int main() 131 | { 132 | int n, q; 133 | std::cin >> n >> q; 134 | 135 | std::vector v(n); 136 | for (int i = 0; i < n; i++) 137 | std::cin >> v[i].mini, v[i].maxi = v[i].mini; 138 | 139 | auto sg = Seg(v.begin(), v.end(), Problem::join, Problem::fix); 140 | 141 | while (q--) { 142 | 143 | int op; 144 | std::cin >> op; 145 | 146 | if (op == 1) { 147 | int val, pos; 148 | std::cin >> val >> pos; 149 | 150 | sg.upd(pos-1, {val, val, 0}); 151 | } 152 | else { 153 | int l, r; 154 | std::cin >> l >> r; 155 | 156 | std::cout << sg.get(l-1, r-1).ans << "\n"; 157 | } 158 | } 159 | } -------------------------------------------------------------------------------- /data_structures/seg_iter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::vector; 4 | 5 | // indexado do 1 6 | struct Seg { 7 | struct Node { 8 | int v; 9 | 10 | Node& add(Node const& rhs) { 11 | this->v += rhs.v; 12 | return *this; 13 | } 14 | 15 | static Node join(Node const& lhs, Node const& rhs) { 16 | Node r = lhs; 17 | r.add(rhs); 18 | return r; 19 | } 20 | }; 21 | 22 | int n; 23 | vector tree; 24 | 25 | Seg(vector const& v) : n(v.size()), tree(n*3) { 26 | for (int i = 0; i < this->n; i++) { 27 | update(i+1, v[i]); 28 | } 29 | } 30 | 31 | inline Node query(int l, int r) { 32 | Node ans{}; 33 | for(l += n, r += n; l < r; l >>= 1, r >>= 1) { 34 | if(l&1) ans.add(tree[l++]); 35 | if(r&1) ans.add(tree[--r]); 36 | } 37 | return ans; 38 | } 39 | 40 | inline void update(int p, int val) { 41 | for(tree[p += n] = Node{val}; p > 1; p >>= 1) { 42 | tree[p >> 1] = Node::join(tree[p], tree[p^1]); 43 | } 44 | } 45 | 46 | inline Node get(int a, int b) { 47 | return query(a+1, b+1); 48 | } 49 | 50 | inline void clear(int pos, int val) { 51 | update(pos+1, val); 52 | } 53 | }; 54 | 55 | int main() { 56 | 57 | } -------------------------------------------------------------------------------- /data_structures/sparse_table.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | template 6 | struct SparseTable 7 | { 8 | int table[size][lsize]; 9 | 10 | int msb(int x) 11 | { 12 | return 31 - __builtin_clz(x); 13 | } 14 | 15 | void build(int *v, int n) 16 | { 17 | for (int i = 1; i <= n; i++) 18 | table[i][0] = v[i]; 19 | 20 | for (int bk = 1; bk < lsize; bk++) { 21 | for (int i = 1; i <= n; i++) { 22 | int ni = i + (1<<(bk-1)); 23 | table[i][bk] = max(table[i][bk-1], table[ni][bk-1]); 24 | } 25 | } 26 | } 27 | 28 | int get(int l, int r) 29 | { 30 | int sz = r-l; 31 | if (sz == 0) return table[l][0]; 32 | 33 | int szb = msb(sz); 34 | int rr = r-(1< st; 44 | 45 | int main() 46 | { 47 | } -------------------------------------------------------------------------------- /data_structures/splay.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | template> 6 | class Splay { 7 | private: 8 | struct Node { 9 | Node *p; 10 | Node *l, *r; 11 | 12 | T val; 13 | 14 | Node(T const& v) : p(nullptr), l(nullptr), r(nullptr), val(v) {}; 15 | }; 16 | 17 | Node *root; 18 | int64_t sz; 19 | Comp comp; 20 | 21 | void lrot(Node *x) { 22 | Node *y = x->r; 23 | if (y) { 24 | x->r = y->l; 25 | if (y->l) y->l->p = x; 26 | y->p = x->p; 27 | } 28 | if (!x->p) root = y; 29 | else if (x->p->l == x) x->p->l = y; 30 | else if (x->p->r == x) x->p->r = y; 31 | if (y) y->l = x; 32 | x->p = y; 33 | } 34 | 35 | void rrot(Node *x) { 36 | Node *y = x->l; 37 | if (y) { 38 | x->l = y->r; 39 | if (y->r) y->r->p = x; 40 | y->p = x->p; 41 | } 42 | if (!x->p) root = y; 43 | else if (x->p->l == x) x->p->l = y; 44 | else if (x->p->r == x) x->p->r = y; 45 | if (y) y->r = x; 46 | x->p = y; 47 | } 48 | 49 | void splay(Node *x) { 50 | while (x->p) { 51 | if (!x->p->p) { 52 | if (x->p->l == x) rrot(x->p); 53 | else lrot(x->p); 54 | } 55 | else if (x->p->l == x and x->p->p->l == x->p) { 56 | rrot(x->p->p); 57 | rrot(x->p); 58 | } 59 | else if (x->p->r == x and x->p->p->r == x->p) { 60 | lrot(x->p->p); 61 | lrot(x->p); 62 | } 63 | else if (x->p->l == x and x->p->p->r == x->p) { 64 | rrot(x->p); 65 | lrot(x->p); 66 | } 67 | else { 68 | lrot(x->p); 69 | rrot(x->p); 70 | } 71 | } 72 | } 73 | 74 | void replace(Node *x, Node *y) { 75 | if (!x->p) root = y; 76 | else if (x == x->p->l) x->p->l = y; 77 | else x->p->r = y; 78 | if (y) y->p = x->p; 79 | } 80 | 81 | void insert(Node *&x, Node *y, Node *p) { 82 | if (!x) { 83 | x = y; 84 | y->p = p; 85 | splay(y); 86 | } 87 | else if (comp(y->val, x->val)) insert(x->l, y, x); 88 | else insert(x->r, y, x); 89 | } 90 | 91 | Node* find(Node *t, T const& v) { 92 | if (!t) return nullptr; 93 | else if (t->val == v) { 94 | splay(t); 95 | return root; 96 | } 97 | else if (comp(v, t->val)) return find(t->l, v); 98 | else return find(t->r, v); 99 | } 100 | 101 | void print(Node *t) { 102 | if (!t) return; 103 | print(t->l); 104 | cout << t->val << " "; 105 | print(t->r); 106 | } 107 | 108 | Node* find_min(Node *t) { 109 | if (!t) return nullptr; 110 | else if (t->l) return find_min(t->l); 111 | else return t; 112 | } 113 | 114 | Node* find_max(Node *t) { 115 | if (!t) return nullptr; 116 | else if (t->r) return find_max(t->r); 117 | else return t; 118 | } 119 | 120 | Node* join(Node *l, Node *r) { 121 | l = find_max(l), r = find_min(r); 122 | splay(l); 123 | splay(r); 124 | l->r = r; 125 | r->p = l; 126 | 127 | return l; 128 | } 129 | 130 | public: 131 | Splay() : root(nullptr), sz(0), comp() {}; 132 | 133 | void insert(T const& v) { 134 | Node *t = new Node(v); 135 | insert(root, t, nullptr); 136 | sz++; 137 | } 138 | 139 | Node const* find(T const& v) { 140 | return find(root, v); 141 | } 142 | 143 | void erase(T const& v) { 144 | Node *t = find(root, v); 145 | if (!t) return; 146 | 147 | sz--; 148 | 149 | if (!t->l) replace(t, t->r); 150 | else if (!t->r) replace(t, t->l); 151 | else { 152 | replace(t, join(t->l, t->r)); 153 | delete t; 154 | } 155 | } 156 | 157 | int64_t size() const { 158 | return sz; 159 | } 160 | 161 | void print() { 162 | print(root); 163 | cout << "\n"; 164 | } 165 | }; 166 | 167 | int main() { 168 | Splay st; 169 | 170 | st.insert(2); 171 | st.insert(4); 172 | st.insert(3); 173 | st.insert(5); 174 | 175 | assert(!st.find(1)); 176 | assert(st.find(2)); 177 | assert(st.find(3)); 178 | assert(st.find(4)); 179 | assert(st.find(5)); 180 | assert(!st.find(6)); 181 | 182 | st.print(); 183 | 184 | st.erase(2); 185 | st.erase(4); 186 | 187 | assert(!st.find(1)); 188 | assert(!st.find(2)); 189 | assert(st.find(3)); 190 | assert(!st.find(4)); 191 | assert(st.find(5)); 192 | assert(!st.find(6)); 193 | 194 | st.print(); 195 | } -------------------------------------------------------------------------------- /data_structures/sqrttree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | template 6 | T operation(T a, T b) 7 | { 8 | return a + b; 9 | } 10 | 11 | template 12 | struct node 13 | { 14 | T *v; 15 | int n, sqt, nsqt; 16 | vector p, s; 17 | vector > b; 18 | vector child; 19 | 20 | node(T *ini, int n_) 21 | { 22 | v = ini; 23 | n = n_; 24 | sqt = sqrt(n); 25 | nsqt = n/sqt + (n%sqt == 0? 0: 1); 26 | p.resize(n); 27 | s.resize(n); 28 | b.resize(nsqt); 29 | 30 | build_p(); 31 | build_s(); 32 | build_b(); 33 | if (n > 1) build_child(); 34 | } 35 | 36 | void build_p() 37 | { 38 | for (int i = 0; i < n; i++) { 39 | 40 | if (i == 0 or i/sqt != (i-1)/sqt) 41 | p[i] = v[i]; 42 | else 43 | p[i] = operation(p[i-1], v[i]); 44 | } 45 | } 46 | 47 | void build_s() 48 | { 49 | for (int i = n-1; i >= 0; i--) { 50 | 51 | if (i == n-1 or i/sqt != (i+1)/sqt) 52 | s[i] = v[i]; 53 | else 54 | s[i] = operation(s[i+1], v[i]); 55 | } 56 | } 57 | 58 | void build_b() 59 | { 60 | for (int i = 0; i < nsqt; i++) { 61 | 62 | int fim = min(n-1, sqt*(i+1)-1); 63 | b[i].resize(nsqt); 64 | b[i][i] = p[fim]; 65 | 66 | for (int j = i+1; j < nsqt; j++) { 67 | 68 | int at = min(n-1, sqt*(j+1)-1); 69 | b[i][j] = operation(b[i][j-1], p[at]); 70 | } 71 | } 72 | } 73 | 74 | void build_child() 75 | { 76 | child.resize(nsqt); 77 | for (int i = 0; i < nsqt; i++) { 78 | 79 | int ini = i*sqt; 80 | int fim = min(n-1, sqt*(i+1)-1); 81 | int se = fim-ini+1; 82 | 83 | child[i] = new node(v+ini, se); 84 | } 85 | } 86 | 87 | T query(int l, int r) 88 | {l 89 | if (l == r) return v[l];l 90 | if (l/sqt != r/sqt) return get(l, r); 91 | 92 | int block = l/sqt; 93 | int ini = block*sqt; 94 | 95 | return child[block]->query(l-ini, r-ini); 96 | } 97 | 98 | T get(int l, int r) 99 | { 100 | int lb = l/sqt + 1; 101 | int rb = r/sqt - 1; 102 | 103 | if (lb == rb+1) return operation(s[l], p[r]); 104 | 105 | return operation(b[lb][rb], operation(s[l], p[r])); 106 | } 107 | }; 108 | 109 | const int maxn = 1000000; 110 | 111 | int v[maxn]; 112 | int ans[maxn]; 113 | 114 | int main() 115 | { 116 | for (int i = 0; i < maxn; i++) v[i] = rand(); 117 | 118 | node *t = new node(v, maxn); 119 | 120 | mt19937 rd; 121 | uniform_int_distribution rnd(0, maxn-1); 122 | 123 | int q = maxn; 124 | 125 | while (q--) { 126 | 127 | int l = rnd(rd); 128 | int r = rnd(rd); 129 | 130 | if (l > r) swap(l, r); 131 | 132 | ans[q] = t->query(l, r); 133 | } 134 | } -------------------------------------------------------------------------------- /data_structures/treap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | template 6 | class Treap { 7 | private: 8 | struct Node 9 | { 10 | T val; 11 | int h, sz; 12 | Node *l, *r; 13 | 14 | Node(T x) 15 | : val(x), h(rand()), sz(1), l(nullptr), r(nullptr) {}; 16 | 17 | friend ostream& operator<<(ostream& out, Node const& t) 18 | { 19 | if (t.l) out << *t.l; 20 | out << t.val << " "; 21 | if (t.r) out << *t.r; 22 | return out; 23 | } 24 | }; 25 | 26 | void op(Node *t) 27 | { 28 | if (!t) return; 29 | t->sz = 1; 30 | if (t->l) t->sz += t->l->sz; 31 | if (t->r) t->sz += t->r->sz; 32 | } 33 | 34 | void merge(Node *&t, Node *l, Node *r) 35 | { 36 | if (!l or !r) 37 | return void(t=l?l:r); 38 | if (l->h > r->h) 39 | merge(l->r, l->r, r), t = l; 40 | else 41 | merge(r->l, l, r->l), t = r; 42 | op(t); 43 | } 44 | 45 | void split(Node *t, Node *&l, Node *&r, T v) 46 | { 47 | if (!t) return void(l=r=nullptr); 48 | if (v > t->val) 49 | split(t->r, t->r, r, v), l = t; 50 | else 51 | split(t->l, l, t->l, v), r = t; 52 | op(l), op(r); 53 | } 54 | 55 | void insert(Node *&t, Node *v) 56 | { 57 | if (!t) return void(t=v); 58 | if (v->h > t->h) split(t, v->l, v->r, v->val), t = v; 59 | else if (t->val <= v->val) insert(t->r, v); 60 | else insert(t->l, v); 61 | op(t); 62 | } 63 | 64 | void erase(Node *&t, T v) 65 | { 66 | if (!t) return; 67 | if (t->val == v) { 68 | Node *aux = t; 69 | merge(t, t->l, t->r); 70 | delete aux; 71 | } 72 | else if (t->val < v) erase(t->r, v); 73 | else erase(t->l, v); 74 | op(t); 75 | } 76 | 77 | T kth(Node *t, int pos) 78 | { 79 | int p = 1; 80 | if (t->l) p += t->l->sz; 81 | 82 | if (p == pos) return t->val; 83 | if (pos > p) return kth(t->r, pos-p); 84 | else return kth(t->l, pos); 85 | } 86 | 87 | int ord(Node *t, T val) 88 | { 89 | Node *aux = nullptr, *r = nullptr; 90 | split(root, aux, r, val); 91 | 92 | int ans = 0; 93 | if (aux) ans = aux->sz; 94 | 95 | merge(root, aux, r); 96 | return ans; 97 | } 98 | 99 | void del(Node *t) 100 | { 101 | if (t->l) del(t->l); 102 | if (t->r) del(t->r); 103 | delete t; 104 | } 105 | 106 | Node *root; 107 | 108 | public: 109 | void insert(T val) 110 | { 111 | Node *aux = new Node(val); 112 | insert(root, aux); 113 | } 114 | 115 | template 116 | void insert(T val, Args... args) 117 | { 118 | insert(val); 119 | insert(args...); 120 | } 121 | 122 | void erase(T val) 123 | { 124 | erase(root, val); 125 | } 126 | 127 | template 128 | void erase(T val, Args... args) 129 | { 130 | erase(val); 131 | erase(args...); 132 | } 133 | 134 | void erase_range(T ini, T fim) 135 | { 136 | Node *l = nullptr, *r = nullptr, *aux=nullptr; 137 | split(root, l, aux, ini); 138 | split(aux, aux, r, fim); 139 | del(aux); 140 | merge(root, l, r); 141 | } 142 | 143 | T kth(int pos) 144 | { 145 | return kth(root, pos+1); 146 | } 147 | 148 | int ord(T val) 149 | { 150 | return ord(root, val); 151 | } 152 | 153 | friend ostream& operator<<(ostream& out, Treap const& tp) 154 | { 155 | if (!tp.root) return out; 156 | out << *tp.root; 157 | return out; 158 | } 159 | 160 | Treap() 161 | { 162 | root = nullptr; 163 | } 164 | 165 | ~Treap() 166 | { 167 | if (root) del(root); 168 | } 169 | }; 170 | 171 | int main() 172 | { 173 | Treap tp; 174 | 175 | tp.insert(3, 1, 5); 176 | cout << tp << "\n"; 177 | 178 | tp.erase(3); 179 | cout << tp << "\n"; 180 | 181 | tp.insert(2, 3, 4); 182 | cout << tp << "\n"; 183 | 184 | cout << tp.kth(4) << "\n"; 185 | cout << tp.ord(5) << "\n"; 186 | 187 | tp.erase_range(2, 5); 188 | cout << tp << "\n"; 189 | } -------------------------------------------------------------------------------- /data_structures/treap_build.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "/home/fred/test_cases/jng.h" 3 | 4 | using namespace std; 5 | 6 | typedef unsigned int ui; 7 | 8 | const int maxn = 10101010; 9 | 10 | struct node 11 | { 12 | int val; 13 | int h, sz; 14 | 15 | node *l, *r; 16 | 17 | node(int val) 18 | : val(val), h(rand()), sz(1), l(nullptr), r(nullptr) {}; 19 | node(int val, int sz) 20 | : val(val), h(0), sz(sz), l(nullptr), r(nullptr) {}; 21 | 22 | }; 23 | 24 | int v[maxn]; 25 | 26 | node* build(int l, int r) 27 | { 28 | if (l == r) return new node(v[l], 1); 29 | if (l > r) return nullptr; 30 | 31 | int m = (l+r)>>1; 32 | 33 | node *at = new node(v[m], r-l+1); 34 | 35 | at->l = build(l, m-1); 36 | at->r = build(m+1, r); 37 | 38 | return at; 39 | } 40 | 41 | int s = 0; 42 | 43 | void fix(int n, node *no) 44 | { 45 | queue q; 46 | q.push(no); 47 | 48 | int step = (ui(-1))/(n+1); 49 | 50 | int at = 0x7fffffff; 51 | at -= step; 52 | 53 | while (!q.empty()) { 54 | 55 | node *t = q.front(); 56 | q.pop(); 57 | 58 | t->h = at; 59 | at -= step; 60 | 61 | if (t->l) q.push(t->l); 62 | if (t->r) q.push(t->r); 63 | } 64 | } 65 | 66 | ostream& operator<<(ostream& out, node *t) 67 | { 68 | if (!t) return out; 69 | 70 | out << t->l << t->val << " "<< t->r; 71 | 72 | return out; 73 | } 74 | 75 | int main() 76 | { 77 | ios_base::sync_with_stdio(false), cin.tie(0); 78 | 79 | int n; 80 | cin >> n; 81 | 82 | for (int i = 0; i < n; i++) cin >> v[i]; 83 | 84 | auto timer = new ContextTimer("build"); 85 | 86 | sort(v, v+n); 87 | 88 | node *t = build(0, n-1); 89 | 90 | fix(n, t); 91 | 92 | delete timer; 93 | 94 | cout << t->val << "\n"; 95 | } -------------------------------------------------------------------------------- /data_structures/treap_impl.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | mt19937 rd{17}; 6 | 7 | template 8 | class Treap { 9 | private: 10 | struct Node { 11 | Node *l, *r; 12 | T val; 13 | uint32_t h, sz; 14 | 15 | Node() = default; 16 | 17 | ~Node() {}; 18 | 19 | Node(T const& x) 20 | : l(nullptr), r(nullptr), val(x), h(rd()), sz(1) {}; 21 | 22 | friend ostream& operator<<(ostream& out, Node const& t) 23 | { 24 | if (t.l) out << *t.l; 25 | out << t.val << " "; 26 | if (t.r) out << *t.r; 27 | return out; 28 | } 29 | }; 30 | 31 | 32 | void op(Node *t) { 33 | if (!t) return; 34 | t->sz = 1; 35 | if (t->l) t->sz += t->l->sz; 36 | if (t->r) t->sz += t->r->sz; 37 | } 38 | 39 | void merge(Node *&t, Node *l, Node *r) { 40 | if (!l or !r) 41 | return void(t=l?l:r); 42 | if (l->h > r->h) 43 | merge(l->r, l->r, r), t = l; 44 | else 45 | merge(r->l, l, r->l), t = r; 46 | op(t); 47 | } 48 | 49 | void split(Node *t, Node *&l, Node *&r, int pos) { 50 | if (!t) return void(l=r=nullptr); 51 | 52 | int p = 1; 53 | if (t->l) p += t->l->sz; 54 | 55 | if (p < pos) 56 | split(t->r, t->r, r, pos-p), l = t; 57 | else 58 | split(t->l, l, t->l, pos), r = t; 59 | op(l), op(r); 60 | } 61 | 62 | void insert(Node *&t, Node *aux, int pos) { 63 | if (!t) { 64 | t = aux; 65 | op(t); 66 | return; 67 | } 68 | 69 | int p = 1; 70 | if (t->l) p += t->l->sz; 71 | 72 | if (t->h < aux->h) split(t, aux->l, aux->r, pos), t = aux; 73 | else if (p >= pos) insert(t->l, aux, pos); 74 | else insert(t->r, aux, pos-p); 75 | 76 | op(t); 77 | } 78 | 79 | void erase(Node *&t, int pos) { 80 | if (!t) return; 81 | 82 | int p = 1; 83 | if (t->l) p += t->l->sz; 84 | 85 | if (p == pos) merge(t, t->l, t->r); 86 | else if (p < pos) erase(t->r, pos-p); 87 | else erase(t->l, pos); 88 | 89 | op(t); 90 | } 91 | 92 | Node& kth(Node *t, int pos) 93 | { 94 | int p = 1; 95 | if (t->l) p += t->l->sz; 96 | 97 | if (p == pos) return *t; 98 | if (pos > p) return kth(t->r, pos-p); 99 | else return kth(t->l, pos); 100 | } 101 | 102 | Node *root = nullptr; 103 | vector aux_new; 104 | int idx = 0; 105 | 106 | Node* _get_ptr(T const& val) { 107 | return ::new (static_cast(&aux_new[idx++])) Node(val); 108 | } 109 | 110 | public: 111 | class Iterator { 112 | public: 113 | stack bt; 114 | Iterator() = default; 115 | Iterator(Iterator&& t) : bt(move(t.bt)) {}; 116 | Iterator(Iterator const& t) : bt(t.bt) {}; 117 | 118 | Iterator& operator=(Iterator&& t) { 119 | return Iterator(move(t)); 120 | } 121 | 122 | Iterator& operator=(Iterator const& t) { 123 | return Iterator(t); 124 | } 125 | 126 | Iterator& operator++() { 127 | Node* t = bt.top(); 128 | 129 | if (!t->r) { 130 | bt.pop(); 131 | return *this; 132 | } 133 | 134 | t = t->r; 135 | bt.pop(); 136 | bt.push(t); 137 | 138 | while (t->l) { 139 | t = t->l; 140 | bt.push(t); 141 | } 142 | 143 | return *this; 144 | } 145 | 146 | Node& operator*() { 147 | return *bt.top(); 148 | } 149 | 150 | Node* operator->() { 151 | return bt.top(); 152 | } 153 | 154 | bool operator==(Iterator const& t) const { 155 | return bt == t.bt; 156 | } 157 | 158 | bool operator!=(Iterator const& t) const { 159 | return !(bt == t.bt); 160 | } 161 | }; 162 | 163 | Iterator begin() { 164 | Iterator it; 165 | Node* t = root; 166 | 167 | while (t and t->l) { 168 | it.bt.push(t); 169 | t = t->l; 170 | } 171 | if (t) it.bt.push(t); 172 | 173 | return it; 174 | } 175 | 176 | Iterator end() { 177 | return Iterator(); 178 | } 179 | 180 | void insert(int pos, T const& val) 181 | { 182 | Node *l = nullptr, *r = nullptr, *aux = _get_ptr(val); 183 | insert(root, aux, pos+1); 184 | } 185 | 186 | void erase(int pos) 187 | { 188 | erase(root, pos+1); 189 | } 190 | 191 | Node& kth(int pos) 192 | { 193 | return kth(root, pos+1); 194 | } 195 | 196 | friend ostream& operator<<(ostream& out, Treap const& tp) 197 | { 198 | if (!tp.root) return out; 199 | out << *tp.root; 200 | return out; 201 | } 202 | 203 | Treap() 204 | { 205 | aux_new.resize(1'000'000); 206 | root = nullptr; 207 | } 208 | }; 209 | 210 | class Timer { 211 | public: 212 | Timer(const std::string& name) : name_(name) { 213 | start_ = std::chrono::steady_clock::now(); 214 | } 215 | 216 | Timer() : Timer("") {} 217 | 218 | Timer(const Timer&) = delete; 219 | Timer& operator=(const Timer&) = delete; 220 | Timer(Timer&&) = delete; 221 | Timer& operator=(Timer&&) = delete; 222 | 223 | ~Timer() { 224 | auto dif = std::chrono::steady_clock::now() - start_; 225 | auto ms = std::chrono::duration_cast(dif); 226 | if (!name_.empty()) { 227 | std::cerr << "[" << name_ << "] "; 228 | } 229 | std::cerr << ms.count() << " ms\n"; 230 | } 231 | 232 | private: 233 | std::string name_; 234 | std::chrono::steady_clock::time_point start_; 235 | }; 236 | 237 | struct Query { 238 | enum class Op{ 239 | INSERT, 240 | ERASE, 241 | QUERY, 242 | } opt; 243 | // Op opt; 244 | int pos, val; 245 | }; 246 | 247 | vector gen_bench(int n, int p_insert, int p_erase, int p_query) { 248 | vector v(n); 249 | 250 | mt19937 rg{13}; 251 | 252 | uniform_int_distribution roll(0, 99); 253 | 254 | int num = 0; 255 | 256 | auto f = [&num, p_insert, p_erase, p_query] (int p) { 257 | if (num == 0 or p < p_insert) { 258 | num++; 259 | return Query::Op::INSERT; 260 | } 261 | else if (p < p_insert+p_erase) { 262 | num--; 263 | return Query::Op::ERASE; 264 | } 265 | else return Query::Op::QUERY; 266 | }; 267 | 268 | for (auto& qr : v) { 269 | int p = roll(rg); 270 | 271 | int pos = uniform_int_distribution(0, num)(rg); 272 | int val = rg(); 273 | qr = {f(p), pos, val}; 274 | } 275 | 276 | return v; 277 | } 278 | 279 | int64_t run_bench(vector const& qrs, Treap& tp) { 280 | Timer timer{"total"}; 281 | int64_t total = 0; 282 | for (auto const& qr : qrs) { 283 | if (qr.opt == Query::Op::INSERT) tp.insert(qr.pos, qr.val); 284 | else if (qr.opt == Query::Op::ERASE) tp.erase(qr.pos); 285 | else total += tp.kth(qr.pos).val; 286 | } 287 | return total; 288 | } 289 | 290 | int main() 291 | { 292 | Treap tp; 293 | 294 | tp.insert(0,3); 295 | tp.insert(1,1); 296 | tp.insert(2,2); 297 | tp.insert(3,5); 298 | tp.insert(4,7); 299 | tp.insert(5,6); 300 | 301 | for (auto it : tp) cout << it.val << "\n"; 302 | 303 | auto ans = run_bench(gen_bench(1'000'000, 60, 20, 20), tp); 304 | 305 | cout << ans << "\n"; 306 | } -------------------------------------------------------------------------------- /data_structures/trie.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class Trie { 6 | private: 7 | struct Node 8 | { 9 | Node* b[26]; 10 | bool fim = false; 11 | }; 12 | 13 | Node* root; 14 | 15 | void add(Node* rt, string const& s) 16 | { 17 | Node *at = rt; 18 | 19 | for (char a : s) { 20 | if (!at->b[a-'a']) 21 | at->b[a-'a'] = new Node(); 22 | at = at->b[a-'a']; 23 | } 24 | at->fim = true; 25 | } 26 | 27 | bool find(Node* rt, string const& s) 28 | { 29 | Node *at = rt; 30 | 31 | for (char a : s) { 32 | if (!at->b[a-'a']) 33 | return false; 34 | at = at->b[a-'a']; 35 | } 36 | return at->fim; 37 | } 38 | public: 39 | void insert(string const& s) 40 | { 41 | add(root, s); 42 | } 43 | 44 | bool find(string const& s) 45 | { 46 | return find(root, s); 47 | } 48 | 49 | Trie() 50 | { 51 | root = new Node(); 52 | } 53 | }; 54 | 55 | int main() 56 | { 57 | Trie tr; 58 | 59 | tr.insert("teste"); 60 | 61 | cout << boolalpha << tr.find("test") << "\n"; 62 | cout << boolalpha << tr.find("teste") << "\n"; 63 | } -------------------------------------------------------------------------------- /data_structures/trie_xor.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class Trie { 6 | private: 7 | struct Node 8 | { 9 | Node* b[2]; 10 | }; 11 | 12 | Node* root; 13 | 14 | void add(Node* rt, int s) 15 | { 16 | Node *at = rt; 17 | 18 | for (int idx = 30; idx >= 0; idx--) { 19 | int now = (s&(1<b[now]) 22 | at->b[now] = new Node(); 23 | at = at->b[now]; 24 | } 25 | } 26 | 27 | int find(Node* rt, int s) 28 | { 29 | Node *at = rt; 30 | 31 | int ans = 0; 32 | for (int idx = 30; idx >= 0; idx--) { 33 | int now = (s&(1<b[now]) 36 | ans |= (now<b[now]; 37 | else 38 | ans |= ((1-now)<b[1-now]; 39 | } 40 | return ans; 41 | } 42 | public: 43 | void insert(int s) 44 | { 45 | add(root, s); 46 | } 47 | 48 | int find(int s) 49 | { 50 | return find(root, s); 51 | } 52 | 53 | Trie() 54 | { 55 | root = new Node(); 56 | } 57 | }; 58 | 59 | int main() 60 | { 61 | Trie tr; 62 | 63 | tr.insert(3); 64 | tr.insert(5); 65 | 66 | cout << tr.find(2) << "\n"; 67 | } -------------------------------------------------------------------------------- /data_structures/wavelet.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef vector vi; 6 | 7 | const int maxn = 100100; 8 | const int maxm = 1000000000; 9 | 10 | int v[maxn]; 11 | 12 | struct wtree 13 | { 14 | int lo, hi; 15 | wtree *l, *r; 16 | vi b; 17 | 18 | wtree(int *from, int *to, int x, int y) 19 | { 20 | lo = x, hi = y; 21 | 22 | if (lo == hi or from >= to) return; 23 | 24 | int mid = (lo+hi)/2; 25 | 26 | auto f = [&](int x) -> bool 27 | { 28 | return x <= mid; 29 | }; 30 | 31 | b.reserve(to-from+1); 32 | b.push_back(0); 33 | 34 | for (auto it = from; it != to; it++) { 35 | 36 | b.push_back(b.back() + f(*it)); 37 | } 38 | 39 | auto pivot = stable_partition(from, to, f); 40 | 41 | l = new wtree(from, pivot, lo, mid); 42 | r = new wtree(pivot, to, mid+1, hi); 43 | } 44 | 45 | // kth element between l and r 46 | int kth(int l, int r, int k) 47 | { 48 | if (l > r) return 0; 49 | if (lo == hi) return lo; 50 | 51 | int inleft = b[r] - b[l-1]; 52 | 53 | int lb = b[l-1]; 54 | int rb = b[r]; 55 | 56 | if (k <= inleft) return this->l->kth(lb+1, rb, k); 57 | return this->r->kth(l-lb, r-rb, k-inleft); 58 | } 59 | 60 | // number of elements between l and r less or equal than k 61 | int lte(int l, int r, int k) 62 | { 63 | if (l > r or k < lo or k > hi) return 0; 64 | 65 | if (hi <= k) return r-l+1; 66 | 67 | int lb = b[l-1], rb = b[r]; 68 | 69 | return this->l->lte(lb+1, rb, k) + this->r->lte(l-lb, r-rb, k); 70 | } 71 | 72 | // number of elements between l and r equal to k 73 | int count(int l, int r, int k) 74 | { 75 | if (l > r or k < lo or k > r) return 0; 76 | 77 | if (lo == hi) return r-l+1; 78 | 79 | int lb = b[l-1], rb = b[r], mid = (l+r)/2; 80 | 81 | if (k <= mid) return this->l->count(lb+1, rb, k); 82 | return this->r->count(l-lb, r-rb, k); 83 | } 84 | 85 | ~wtree() 86 | { 87 | delete l; 88 | delete r; 89 | } 90 | }; 91 | 92 | int main() 93 | { 94 | ios_base::sync_with_stdio(false); 95 | // cin.tie(0); 96 | 97 | int n; 98 | cin >> n; 99 | 100 | for (int i = 1; i <= n; i++) cin >> v[i]; 101 | 102 | wtree *t = new wtree(v+1, v+n+1, 1, maxm); 103 | 104 | int q; 105 | cin >> q; 106 | 107 | while (q--) { 108 | 109 | int l, r, k; 110 | cin >> l >> r >> k; 111 | 112 | int res = t->kth(l, r, k); 113 | 114 | cout << res << "\n"; 115 | } 116 | 117 | return 0; 118 | } -------------------------------------------------------------------------------- /data_structures/wavelet_static.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LEFT ((no*2)+1) 4 | #define RIGHT ((no*2)+2) 5 | 6 | using namespace std; 7 | 8 | typedef vector vi; 9 | 10 | const int maxn = 100010; 11 | const int maxm = maxn; 12 | 13 | int v[maxn]; 14 | vi b[maxn*4]; 15 | int mid; 16 | 17 | inline bool f(int x) 18 | { 19 | return x <= mid; 20 | } 21 | 22 | void build(int no, int *from, int *to, int lo, int hi) 23 | { 24 | if (from >= to or lo == hi) return; 25 | 26 | mid = (lo+hi)/2; 27 | 28 | b[no].push_back(0); 29 | 30 | for (int *it = from; it != to; it++) { 31 | 32 | b[no].push_back(b[no].back() + f(*it)); 33 | } 34 | 35 | int *pivot = stable_partition(from, to, f); 36 | 37 | build(LEFT, from, pivot, lo, mid); 38 | mid = (lo+hi)/2; 39 | build(RIGHT, pivot, to, mid+1, hi); 40 | } 41 | 42 | int kth(int no, int lo, int hi, int l, int r, int k) 43 | { 44 | if (l > r) return 0; 45 | 46 | if (lo == hi) return lo; 47 | 48 | mid = (lo+hi)/2; 49 | 50 | int lb = b[no][l-1]; 51 | int rb = b[no][r]; 52 | int inleft = rb - lb; 53 | 54 | if (inleft >= k) return kth(LEFT, lo, mid, lb+1, rb, k); 55 | return kth(RIGHT, mid+1, hi, l-lb, r-rb, k-inleft); 56 | } 57 | 58 | int main() 59 | { 60 | int n, q; 61 | cin >> n >> q; 62 | 63 | for (int i = 1; i <= n; i++) cin >> v[i]; 64 | 65 | build(0, v+1, v+1+n, 1, maxm); 66 | 67 | while (q--) { 68 | 69 | int l, r, k; 70 | cin >> l >> r >> k; 71 | 72 | int res = kth(0, 1, maxm, l, r, k); 73 | 74 | cout << res << "\n"; 75 | } 76 | 77 | return 0; 78 | } -------------------------------------------------------------------------------- /dynamic_programming/divide_and_conquer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int const maxn = 101010; 6 | int const maxk = 11; 7 | int const inf = 0x3f3f3f3f; 8 | 9 | int v[maxn], pref[maxn]; 10 | int dp[maxk][maxn]; 11 | 12 | int f(int i, int j) { 13 | return (pref[j]-pref[i-1]) * (j-i+1); 14 | } 15 | 16 | void solve(int k, int l, int r, int optl, int optr) 17 | { 18 | if (l > r) return; 19 | 20 | int m = (l+r)/2; 21 | 22 | dp[k][m] = inf; 23 | int opt = m; 24 | 25 | int cost = 0; 26 | for (int i = m-1; i > optr; i--) cost += f(i, m); 27 | 28 | for (int i = min(optr, m); i >= optl; i--) { 29 | cost += f(i, m); 30 | if (cost + dp[k-1][i-1] < dp[k][m]) { 31 | dp[k][m] = cost + dp[k-1][i-1]; 32 | opt = i; 33 | } 34 | } 35 | 36 | solve(k, l, m-1, optl, opt); 37 | solve(k, m+1, r, opt, optr); 38 | } 39 | 40 | int main() 41 | { 42 | 43 | } -------------------------------------------------------------------------------- /dynamic_programming/knapsack_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int maxn = 1010; 6 | const int maxm = 101010; 7 | 8 | int w[maxn], c[maxn]; 9 | int d[maxm]; 10 | 11 | int main() 12 | { 13 | int n, m; 14 | cin >> n >> m; 15 | 16 | for (int i = 1; i <= n; i++) 17 | cin >> w[i] >> c[i]; 18 | 19 | memset(d, -1, sizeof(d)); 20 | d[0] = 0; 21 | 22 | for (int i = 1; i <= n; i++) 23 | for (int j = m; j >= w[i]; j--) 24 | if (d[j-w[i]] >= 0) 25 | d[j] = max(d[j], d[j-w[i]]+c[i]); 26 | 27 | int ans = 0; 28 | for (int i = 0; i <= m; i++) 29 | ans = max(ans, d[i]); 30 | 31 | cout << ans << "\n"; 32 | } -------------------------------------------------------------------------------- /dynamic_programming/knapsack_bitset.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int const maxn = 101; 7 | int const maxm = 100000001; 8 | 9 | int v[maxn]; 10 | // must to have two bitsets as one serves as temporary to avoid 11 | // stack oveflow which happens when large bitsets are implicitly 12 | // allocated eg. dp |= dp< dp, dp2; 14 | 15 | // find first value > m that cannot be formed by the sums of 16 | // numbers from v 17 | int main() 18 | { 19 | int n, m; 20 | cin >> n >> m; 21 | 22 | for (int i = 0; i < n; i++) cin >> v[i]; 23 | 24 | dp[0] = true; 25 | dp2[0] = true; 26 | for (int i = 0; i < n; i++) { 27 | dp2 <<= v[i]; 28 | dp |= dp2; 29 | dp2 = dp; 30 | } 31 | 32 | dp.flip(); 33 | cout << dp._Find_next(m) << "\n"; 34 | } 35 | -------------------------------------------------------------------------------- /dynamic_programming/knapsack_bounded.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ff first 4 | #define ss second 5 | 6 | using namespace std; 7 | 8 | typedef pair ii; 9 | 10 | struct minqueue 11 | { 12 | deque dq; 13 | 14 | int l, r, sum; 15 | 16 | void clear() 17 | { 18 | l = r = sum = 0; 19 | dq.clear(); 20 | } 21 | 22 | void push(int x) 23 | { 24 | while (!dq.empty() and dq.back().ff > x-sum) dq.pop_back(); 25 | dq.push_back({x-sum,r}); 26 | r++; 27 | } 28 | 29 | void pop() 30 | { 31 | if (!dq.empty() and dq.front().ss == l) dq.pop_front(); 32 | l++; 33 | } 34 | 35 | void add(int x) {sum += x;} 36 | 37 | int getmin() {return dq[0].ff+sum;} 38 | 39 | int size() {return r-l;} 40 | }; 41 | 42 | const int maxn = 1000; 43 | const int maxm = 100000; 44 | const int inf = 0x3f3f3f; 45 | 46 | minqueue q[maxm]; 47 | 48 | int d[maxm]; 49 | int w[maxn], e[maxn], c[maxn]; 50 | 51 | int main() 52 | { 53 | int n, m; 54 | cin >> n >> m; 55 | 56 | for (int i = 1; i <= n; i++) cin >> w[i] >> e[i] >> c[i]; 57 | 58 | for (int i = 1; i <= m; i++) d[i] = inf; 59 | 60 | for (int i = 1; i <= n; i++) { 61 | 62 | for (int j = 0; j < w[i]; j++) q[j].clear(); 63 | 64 | for (int j = 0; j <= m; j++) { 65 | 66 | minqueue& mq = q[j%w[i]]; 67 | 68 | if (mq.size() > e[i]) mq.pop(); 69 | 70 | mq.add(c[i]); 71 | mq.push(d[j]); 72 | 73 | d[j] = mq.getmin(); 74 | } 75 | } 76 | 77 | for (int i = 0; i <= m; i++) cout << d[i] << " "; 78 | cout << "\n"; 79 | } -------------------------------------------------------------------------------- /dynamic_programming/knapsack_unbounded.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int maxn = 1010; 6 | const int maxm = 101010; 7 | 8 | int w[maxn], c[maxn]; 9 | int d[maxm]; 10 | 11 | int main() 12 | { 13 | int n, m; 14 | cin >> n >> m; 15 | 16 | for (int i = 1; i <= n; i++) 17 | cin >> w[i] >> c[i]; 18 | 19 | memset(d, -1, sizeof(d)); 20 | d[0] = 0; 21 | 22 | for (int i = 1; i <= m; i++) 23 | for (int j = 1; j <= n; j++) 24 | if (w[j] <= i and d[i-w[j]] >= 0) 25 | d[i] = max(d[i], d[i-w[j]] + c[j]); 26 | 27 | int ans = 0; 28 | for (int i = 0; i <= m; i++) 29 | ans = max(ans, d[i]); 30 | 31 | cout << ans << "\n"; 32 | } -------------------------------------------------------------------------------- /dynamic_programming/lcs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int maxn = 1010; 6 | 7 | int n, m; 8 | 9 | int a[maxn], b[maxn]; 10 | int dp[maxn][maxn]; 11 | 12 | int solve(int i, int j) 13 | { 14 | if (i > n or j > m) return 0; 15 | if (dp[i][j] >= 0) return dp[i][j]; 16 | 17 | if (a[i] == b[j]) return dp[i][j] = 1 + solve(i+1, j+1); 18 | 19 | return dp[i][j] = max(solve(i+1, j), solve(i, j+1)); 20 | } 21 | 22 | int d[2][maxn]; 23 | 24 | int main() 25 | { 26 | memset(dp, -1, sizeof(dp)); 27 | 28 | cin >> n >> m; 29 | 30 | for (int i = 1; i <= n; i++) 31 | cin >> a[i]; 32 | for (int i = 1; i <= m; i++) 33 | cin >> b[i]; 34 | 35 | int ans = solve(1, 1); 36 | cout << ans << "\n"; 37 | 38 | int now = 0, old = 1; 39 | 40 | for (int i = n; i >= 1; --i) { 41 | swap(now, old); 42 | for (int j = m; j >= 1; --j) { 43 | if (a[i] == b[j]) d[now][j] = 1 + d[old][j+1]; 44 | else d[now][j] = max(d[old][j], 45 | d[now][j+1]); 46 | } 47 | } 48 | 49 | cout << d[now][1] << "\n"; 50 | } -------------------------------------------------------------------------------- /dynamic_programming/lis.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | template 6 | struct Bit 7 | { 8 | int b[sz]; 9 | 10 | void upd(int x, int val) 11 | { 12 | for (int i = x; i < sz; i += i&-i) 13 | b[i] = max(b[i], val); 14 | } 15 | 16 | int get(int x) 17 | { 18 | int ans = 0; 19 | for (int i = x; i; i -= i&-i) 20 | ans = max(ans, b[i]); 21 | return ans; 22 | } 23 | }; 24 | 25 | template 26 | void compress(T* v, int n) 27 | { 28 | vector vv(n+1); 29 | for (int i = 1; i <= n; i++) 30 | vv[i] = v[i]; 31 | 32 | sort(vv.begin()+1, vv.end()); 33 | 34 | for (int i = 1; i <= n; i++) 35 | v[i] = lower_bound(vv.begin()+1, vv.end(), v[i]) - vv.begin(); 36 | } 37 | 38 | const int maxn = 101010; 39 | 40 | int v[maxn]; 41 | Bit bt; 42 | 43 | int main() 44 | { 45 | int n; 46 | cin >> n; 47 | 48 | for (int i = 1; i <= n; i++) 49 | cin >> v[i]; 50 | 51 | compress(v, n); 52 | 53 | for (int i = 1; i <= n; i++) { 54 | int x = bt.get(v[i]-1); 55 | bt.upd(v[i], x+1); 56 | } 57 | 58 | int ans = bt.get(n); 59 | 60 | cout << ans << "\n"; 61 | } -------------------------------------------------------------------------------- /dynamic_programming/subset_sums.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | using ll = long long; 6 | 7 | vector all_sums(vector const& v) 8 | { 9 | vector ans(1<> n >> a >> b; 32 | 33 | vector v(n); 34 | for (int i = 0; i < n; i++) cin >> v[i]; 35 | 36 | int mid = n/2; 37 | vector v1(v.begin(), v.begin()+mid); 38 | vector v2(v.begin()+mid, v.end()); 39 | 40 | auto s1 = all_sums(v1), s2 = all_sums(v2); 41 | 42 | reverse(s1.begin(), s1.end()); 43 | 44 | ll ans = 0; 45 | auto l = s2.begin(), r = s2.begin(); 46 | for (ll i : s1) { 47 | // amount of numbers in range [a, b] 48 | // using two-pointers technique 49 | while (r != s2.end() and *r+i <= b) ++r; 50 | while (l != s2.end() and *l+i < a) ++l; 51 | ans += r-l; 52 | 53 | } 54 | 55 | // overall complexity O(2^(n/2)) ~ O(1.41^n) 56 | cout << ans << "\n"; 57 | } -------------------------------------------------------------------------------- /etc/bitset_extra.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | bitset<100> bt; 8 | cin >> bt; 9 | 10 | cout << bt[0] << "\n"; 11 | cout << bt.count() << "\n"; 12 | cout << (~bt).none() << "\n"; 13 | cout << (~bt).any() << "\n"; 14 | cout << (~bt).all() << "\n"; 15 | cout << bt._Find_first() << "\n"; 16 | cout << bt._Find_next(10) << "\n"; 17 | 18 | cout << bt << "\n"; 19 | } -------------------------------------------------------------------------------- /etc/compression.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // compresses values in positions [ini, fim) to [pos, n+pos] 6 | template 7 | void compress(Iter ini, Iter fim, int pos=1) 8 | { 9 | using T = typename decay::type; 10 | 11 | vector vv(ini, fim); 12 | sort(vv.begin(), vv.end()); 13 | vv.erase(unique(vv.begin(), vv.end()), vv.end()); 14 | 15 | for_each(ini, fim, [&] (T& x) { 16 | x = lower_bound(vv.begin(), vv.end(), x) - vv.begin() + pos; 17 | }); 18 | } 19 | 20 | int va[] = {0, 1000, 2000, 5000, 3000}; 21 | vector v{1000, 2000, 5000, 3000}; 22 | 23 | int main() 24 | { 25 | compress(va+1, va+5); 26 | compress(v.begin(), v.end(), 0); 27 | 28 | for (int i = 1; i <= 4; i++) 29 | cout << va[i] << " "; 30 | cout << "\n"; 31 | 32 | for (int i : v) cout << i << " "; 33 | cout << "\n"; 34 | } 35 | -------------------------------------------------------------------------------- /etc/fast_input.cpp: -------------------------------------------------------------------------------- 1 | inline int scan () { 2 | int result = 0; 3 | char ch; 4 | bool minus = false; 5 | ch = getchar_unlocked(); 6 | while (true) { 7 | if (ch == '-') break; 8 | if (ch >= '0' && ch <= '9') break; 9 | ch = getchar_unlocked(); 10 | } 11 | if (ch == '-') minus = true; else result = ch-'0'; 12 | while (true) { 13 | ch = getchar_unlocked(); 14 | if (ch < '0' || ch > '9') break; 15 | result = result*10 + (ch - '0'); 16 | } 17 | if (minus) return -result; 18 | return result; 19 | } 20 | 21 | 22 | /*------------------------------------------*/ 23 | /*-----------FUDEROSAMENTE RAPIDO-----------*/ 24 | /*------------------------------------------*/ 25 | 26 | inline int readChar(); 27 | template inline T readInt(); 28 | template inline void writeInt( T x, char end = 0 ); 29 | inline void writeChar( int x ); 30 | inline void writeWord( const char *s ); 31 | 32 | /** Read */ 33 | 34 | static const int buf_size = 4096; 35 | 36 | inline int getChar() { 37 | static char buf[buf_size]; 38 | static int len = 0, pos = 0; 39 | if (pos == len) 40 | pos = 0, len = fread(buf, 1, buf_size, stdin); 41 | if (pos == len) 42 | return -1; 43 | return buf[pos++]; 44 | } 45 | 46 | inline int readChar() { 47 | int c = getChar(); 48 | while (c <= 32) 49 | c = getChar(); 50 | return c; 51 | } 52 | 53 | template 54 | inline T readInt() { 55 | char c = readChar(); 56 | T x = 0; 57 | while ('0' <= c && c <= '9') 58 | x = x * 10 + c - '0', c = getChar(); 59 | return x; 60 | } 61 | 62 | /** Write */ 63 | 64 | static int write_pos = 0; 65 | static char write_buf[buf_size]; 66 | 67 | inline void writeChar( int x ) { 68 | if (write_pos == buf_size) 69 | fwrite(write_buf, 1, buf_size, stdout), write_pos = 0; 70 | write_buf[write_pos++] = x; 71 | } 72 | 73 | template 74 | inline void writeInt( T x, char end ) { 75 | if (x < 0) 76 | writeChar('-'), x = -x; 77 | 78 | char s[24]; 79 | int n = 0; 80 | while (x || !n) 81 | s[n++] = '0' + x % 10, x /= 10; 82 | while (n--) 83 | writeChar(s[n]); 84 | if (end) 85 | writeChar(end); 86 | } 87 | 88 | inline void writeWord( const char *s ) { 89 | while (*s) 90 | writeChar(*s++); 91 | } 92 | 93 | struct Flusher { 94 | ~Flusher() { 95 | if (write_pos) 96 | fwrite(write_buf, 1, write_pos, stdout), write_pos = 0; 97 | } 98 | } flusher; -------------------------------------------------------------------------------- /etc/seed_random.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct random_seeder 6 | { 7 | template 8 | void generate(T begin, T end) const 9 | { 10 | for (random_device r; begin != end; ++begin) 11 | *begin = r(); 12 | } 13 | } sd; 14 | 15 | int main() 16 | { 17 | mt19937_64 rnd{sd}; 18 | 19 | uniform_int_distribution rng(0, 255); 20 | 21 | for (int i = 0; i < 10; i++) cout << char(rng(rnd)); 22 | 23 | return 0; 24 | } -------------------------------------------------------------------------------- /geometry/convex_hull.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | 7 | template 8 | struct Point 9 | { 10 | T x, y; 11 | 12 | Point operator+(Point const& rhs) const 13 | { 14 | return {x+rhs.x, y+rhs.y}; 15 | } 16 | 17 | Point operator-(Point const& rhs) const 18 | { 19 | return {x-rhs.x, y-rhs.y}; 20 | } 21 | 22 | T operator*(Point const& rhs) const 23 | { 24 | return x*rhs.x + y*rhs.y; 25 | } 26 | 27 | T operator^(Point const& rhs) const 28 | { 29 | return x*rhs.y - y*rhs.x; 30 | } 31 | 32 | bool operator<(Point const& rhs) const 33 | { 34 | if (x == rhs.x) return y < rhs.y; 35 | return x < rhs.x; 36 | } 37 | }; 38 | 39 | vector> points; 40 | 41 | int main() 42 | { 43 | int n; 44 | cin >> n; 45 | 46 | for (int i = 0; i < n; i++) { 47 | ll x, y; 48 | cin >> x >> y; 49 | 50 | points.push_back({x, y}); 51 | } 52 | 53 | sort(points.begin(), points.end()); 54 | 55 | vector> up, down; 56 | 57 | for (Point pt : points) { 58 | while (up.size() >= 2 and 59 | ((pt-up.back())^(*(up.end()-2)-up.back())) > 0) 60 | up.pop_back(); 61 | while (down.size() >= 2 and 62 | ((pt-down.back())^(*(down.end()-2)-down.back())) < 0) 63 | down.pop_back(); 64 | up.push_back(pt); 65 | down.push_back(pt); 66 | } 67 | 68 | cout << "Up hull\n"; 69 | for (Point const& pt : up) 70 | cout << pt.x << " " << pt.y << "\n"; 71 | 72 | cout << "Down hull\n"; 73 | for (Point const& pt : down) 74 | cout << pt.x << " " << pt.y << "\n"; 75 | } 76 | -------------------------------------------------------------------------------- /geometry/point.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | 7 | template 8 | struct Point 9 | { 10 | T x, y; 11 | 12 | Point operator+(Point const& rhs) 13 | { 14 | return {x+rhs.x, y+rhs.y}; 15 | } 16 | 17 | Point operator-(Point const& rhs) 18 | { 19 | return {x-rhs.x, y-rhs.y}; 20 | } 21 | 22 | T operator*(Point const& rhs) 23 | { 24 | return x*rhs.x + y*rhs.y; 25 | } 26 | 27 | T operator^(Point const& rhs) 28 | { 29 | return x*rhs.y - y*rhs.x; 30 | } 31 | }; 32 | 33 | int main() 34 | { 35 | Point a, b; 36 | Point aa, bb; 37 | } -------------------------------------------------------------------------------- /geometry/rectangle_union.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | using ll = long long; 6 | 7 | int const maxn = 101010; 8 | 9 | struct Rectangle { 10 | int x1, x2, y1, y2; 11 | }; 12 | 13 | enum class Ev { 14 | ini = 1, 15 | fim = -1, 16 | }; 17 | 18 | struct Event { 19 | int x; 20 | int y1, y2; 21 | Ev type; 22 | 23 | bool operator<(Event const& rhs) const { 24 | if (x == rhs.x) return type > rhs.type; 25 | return x < rhs.x; 26 | } 27 | }; 28 | 29 | struct Seg { 30 | struct Node { 31 | int sum, cnt; 32 | }; 33 | 34 | int n; 35 | vector tree; 36 | 37 | void join(int no, int l, int r) { 38 | if (l == r) { 39 | tree[no].sum = (tree[no].cnt >= 1); 40 | } 41 | else if (tree[no].cnt == 0) { 42 | tree[no].sum = tree[no*2+1].sum + tree[no*2+2].sum; 43 | } 44 | else { 45 | tree[no].sum = r-l+1; 46 | } 47 | } 48 | 49 | void upd(int no, int l, int r, int a, int b, Ev add) { 50 | if (a <= l and r <= b) { 51 | tree[no].cnt += static_cast(add); 52 | 53 | join(no, l, r); 54 | } 55 | else { 56 | int m = (l+r)/2; 57 | 58 | if (b <= m) upd(no*2+1, l, m, a, b, add); 59 | else if (a > m) upd(no*2+2, m+1, r, a, b, add); 60 | else { 61 | upd(no*2+1, l, m, a, b, add); 62 | upd(no*2+2, m+1, r, a, b, add); 63 | } 64 | 65 | join(no, l, r); 66 | } 67 | } 68 | 69 | void upd(int a, int b, Ev add) { 70 | upd(0, 0, n, a, b, add); 71 | } 72 | 73 | int get() { 74 | return tree[0].sum; 75 | } 76 | 77 | Seg(int n) : n(n), tree(n*4) {}; 78 | 79 | void clear() { 80 | fill(tree.begin(), tree.end(), Node{0, 0}); 81 | } 82 | }; 83 | 84 | 85 | ll sweep(Seg& seg, vector const& ev) { 86 | ll ans = 0; 87 | seg.clear(); 88 | 89 | int last = ev.front().x; 90 | 91 | for (auto&& e : ev) { 92 | ans += ll(e.x - last) * (seg.get()); 93 | seg.upd(e.y1, e.y2, e.type); 94 | last = e.x; 95 | } 96 | 97 | return ans; 98 | } 99 | 100 | ll rectangle_union(Seg& seg, vector const& v) { 101 | vector r; 102 | 103 | for (auto&& rect : v) { 104 | r.push_back(Event{rect.x1, rect.y1, rect.y2, Ev::ini}); 105 | r.push_back(Event{rect.x2 + 1, rect.y1, rect.y2, Ev::fim}); 106 | } 107 | 108 | sort(r.begin(), r.end()); 109 | 110 | return sweep(seg, r); 111 | } 112 | 113 | -------------------------------------------------------------------------------- /graph/bfs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int maxn = 101010; 6 | 7 | vector v[maxn]; 8 | int vis[maxn]; 9 | 10 | void bfs(int x) 11 | { 12 | queue q; 13 | q.push(x); 14 | vis[x] = 1; 15 | 16 | while (!q.empty()) { 17 | int at = q.front(); 18 | q.pop(); 19 | 20 | // body 21 | for (int u : v[at]) { 22 | if (!vis[u]) { 23 | vis[u] = 1; 24 | q.push(u); 25 | } 26 | } 27 | 28 | // after 29 | } 30 | } 31 | 32 | int main() 33 | { 34 | 35 | } -------------------------------------------------------------------------------- /graph/biconnected_component.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int const maxn = 101010; 5 | 6 | int n; 7 | vector v[maxn]; 8 | 9 | struct BiconnectedComponent { 10 | vector low, num, s; 11 | vector> components; 12 | int counter; 13 | 14 | BiconnectedComponent() : num(n, -1), low(n, -1), counter(0) { 15 | for (int i = 0; i < n; i++) 16 | if (num[i] < 0) 17 | dfs(i, 1); 18 | } 19 | 20 | void dfs(int x, int isRoot, int p) { 21 | low[x] = num[x] = ++counter; 22 | if (v[x].empty()) { 23 | components.push_back(vector(1, x)); 24 | return; 25 | } 26 | s.push_back(x); 27 | 28 | for (int u : v[x]) { 29 | if (num[u] > -1) low[x] = min(low[x], num[u]); 30 | else { 31 | dfs(u, 0, x); 32 | low[x] = min(low[x], low[u]); 33 | 34 | if (isRoot || low[u] >= num[x]) { 35 | components.push_back(vector(1, x)); 36 | while (1) { 37 | int k = s.back(); 38 | s.pop_back(); 39 | components.back().push_back(k); 40 | if (k == u) break; 41 | } 42 | } 43 | } 44 | } 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /graph/bridge_articulation.cpp: -------------------------------------------------------------------------------- 1 | struct UndirectedDfs { 2 | vector low, num, parent; 3 | vector articulation; 4 | int counter, root, children; 5 | 6 | vector< pair > bridges; 7 | vector cuts; 8 | 9 | UndirectedDfs() : low(V, 0), num(V, -1), parent(V, 0), articulation(V, false), 10 | counter(0), children(0) { 11 | for(int i = 0; i < V; ++i) if (num[i] == -1) { 12 | root = i; children = 0; 13 | dfs(i); 14 | articulation[root] = (children > 1); 15 | } 16 | for(int i = 0; i < V; ++i) 17 | if (articulation[i]) cuts.push_back(i); 18 | } 19 | private: 20 | void dfs(int u) { 21 | low[u] = num[u] = counter++; 22 | for(int j = 0; j < (int) G[u].size(); ++j) { 23 | int v = G[u][j]; 24 | if (num[v] == -1) { 25 | parent[v] = u; 26 | if (u == root) children++; 27 | dfs(v); 28 | if (low[v] >= num[u]) 29 | articulation[u] = true; 30 | if (low[v] > num[u]) bridges.push_back(make_pair(u, v)); 31 | low[u] = min(low[u], low[v]); 32 | } else if (v != parent[u]) 33 | low[u] = min(low[u], num[v]); 34 | } 35 | } 36 | }; -------------------------------------------------------------------------------- /graph/centroid_decomposition.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | using ii = pair; 6 | 7 | const int inf = 0x3f3f3f3f; 8 | const int maxn = 200010; 9 | 10 | int n, k; 11 | vector v[maxn]; 12 | 13 | int sz[maxn]; 14 | int cvis[maxn]; 15 | 16 | int tam(int x, int p) 17 | { 18 | sz[x] = 1; 19 | 20 | for (int u : v[x]) { 21 | if (cvis[u] or u == p) continue; 22 | 23 | sz[x] += tam(u, x); 24 | } 25 | 26 | return sz[x]; 27 | } 28 | 29 | int tot; 30 | ii best; 31 | 32 | void split(int x, int p) 33 | { 34 | int heav = tot - sz[x]; 35 | 36 | for (int u : v[x]) { 37 | if (cvis[u] or u == p) continue; 38 | 39 | heav = max(heav, sz[u]); 40 | split(u, x); 41 | } 42 | 43 | if (best.second > heav) best = {x, heav}; 44 | } 45 | 46 | int centroid(int x) 47 | { 48 | tot = tam(x, x); 49 | best = {0, inf}; 50 | split(x, x); 51 | return best.first; 52 | } 53 | 54 | void solve(int x) 55 | { 56 | int cent = centroid(x); 57 | cvis[cent] = 1; 58 | 59 | for (int u : v[cent]) { 60 | if (cvis[u]) continue; 61 | solve(u); 62 | } 63 | } 64 | 65 | int main() 66 | { 67 | 68 | } -------------------------------------------------------------------------------- /graph/dfs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int maxn = 101010; 6 | 7 | vector v[maxn]; 8 | int vis[maxn]; 9 | 10 | // if general graph 11 | int dfs(int x) 12 | { 13 | vis[x] = 1; 14 | // body 15 | for (int u : v[x]) 16 | if (!vis[u]) dfs(u); 17 | // after 18 | } 19 | 20 | // if tree 21 | int dfs(int x, int p) 22 | { 23 | // body 24 | for (int u : v[x]) { 25 | if (u == p) continue; 26 | dfs(u, x); 27 | } 28 | // after 29 | } -------------------------------------------------------------------------------- /graph/dijkstra.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef pair ii; 6 | 7 | const int maxn = 10101; 8 | 9 | ii v[maxn]; 10 | int dist[maxn]; 11 | 12 | void sssp(int x) 13 | { 14 | memset(dist, 0x3f, sizeof(dist)); 15 | dist[x] = 0; 16 | 17 | priority_queue, greater> pq; 18 | pq.push({0, x}); 19 | 20 | while (!pq.empty()) { 21 | int at, w; 22 | tie(w, at) = pq.top(); 23 | pq.pop(); 24 | 25 | if (w > dist[at]) continue; 26 | 27 | for (ii uu : v[at]) { 28 | int u, ww; 29 | tie(u, ww) = uu; 30 | 31 | if (dist[u] > w+ww) { 32 | dist[u] = w+ww; 33 | pq.push({dist[u], u}); 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /graph/dinic.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | using namespace std; 4 | 5 | #define pb push_back 6 | #define eb emplace_back 7 | #define fi first 8 | #define se second 9 | #define mk make_pair 10 | 11 | typedef long long ll; 12 | typedef pair pii; 13 | 14 | const ll INF = 0x3f3f3f3f3f3f3f3f; 15 | const int MAXN = 1e5 + 5; 16 | 17 | template 18 | struct Dinic { 19 | static constexpr T flow_inf = 1e18; 20 | 21 | struct FlowEdge { 22 | int v, u; 23 | T cap, flow = 0; 24 | FlowEdge(int v, int u, T cap) : v(v), u(u), cap(cap) {} 25 | }; 26 | 27 | vector edges; 28 | vector> adj; 29 | int n, m = 0; 30 | int s, t; 31 | vector level, ptr; 32 | queue q; 33 | 34 | Dinic(int n, int s, int t) : n(n), s(s), t(t) { 35 | adj.resize(n); 36 | level.resize(n); 37 | ptr.resize(n); 38 | } 39 | 40 | void add_edge(int v, int u, T cap) { 41 | edges.emplace_back(v, u, cap); 42 | edges.emplace_back(u, v, 0); 43 | adj[v].push_back(m); 44 | adj[u].push_back(m + 1); 45 | m += 2; 46 | } 47 | 48 | bool bfs() { 49 | while (!q.empty()) { 50 | int v = q.front(); 51 | q.pop(); 52 | for (int id : adj[v]) { 53 | if (edges[id].cap - edges[id].flow <= 0) 54 | continue; 55 | if (level[edges[id].u] != -1) 56 | continue; 57 | level[edges[id].u] = level[v] + 1; 58 | q.push(edges[id].u); 59 | } 60 | } 61 | return level[t] != -1; 62 | } 63 | 64 | T dfs(int v, T pushed) { 65 | if (pushed == 0) return 0; 66 | 67 | if (v == t) return pushed; 68 | 69 | for (int& cid = ptr[v]; cid < (int)adj[v].size(); cid++) { 70 | int id = adj[v][cid]; 71 | int u = edges[id].u; 72 | 73 | if (level[v] + 1 != level[u] || edges[id].cap - edges[id].flow <= 0) continue; 74 | 75 | T tr = dfs(u, min(pushed, edges[id].cap - edges[id].flow)); 76 | 77 | if (tr == 0) continue; 78 | 79 | edges[id].flow += tr; 80 | edges[id ^ 1].flow -= tr; 81 | 82 | return tr; 83 | } 84 | return 0; 85 | } 86 | 87 | T flow() { 88 | T f = 0; 89 | while (true) { 90 | fill(level.begin(), level.end(), -1); 91 | level[s] = 0; 92 | q.push(s); 93 | if (!bfs()) 94 | break; 95 | fill(ptr.begin(), ptr.end(), 0); 96 | while (T pushed = dfs(s, flow_inf)) { 97 | f += pushed; 98 | } 99 | } 100 | return f; 101 | } 102 | }; 103 | -------------------------------------------------------------------------------- /graph/eulerian_path.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int const maxn = 101010; 7 | 8 | vector v[maxn]; 9 | int at[maxn]; 10 | 11 | void dfs(int x, vector& r) { 12 | while (at[x] < (int)v[x].size()) { 13 | int u = v[x][at[x]]; 14 | at[x]++; 15 | 16 | dfs(u, r); 17 | } 18 | r.push_back(x); 19 | } 20 | 21 | int main() { 22 | 23 | } -------------------------------------------------------------------------------- /graph/hld.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int const maxn = 101010; 6 | 7 | vector v[maxn]; 8 | int val[maxn]; 9 | 10 | struct Seg { 11 | Seg(int n) : n(n), tree(n*4) {}; 12 | 13 | void upd(int pos, int val) { 14 | upd(1, 0, n-1, pos, val); 15 | } 16 | 17 | int get(int a, int b) { 18 | return get(1, 0, n-1, a, b); 19 | } 20 | 21 | private: 22 | int n; 23 | vector tree; 24 | 25 | void upd(int no, int l, int r, int pos, int val) { 26 | if (l == r) { 27 | tree[no] = val; 28 | return; 29 | } 30 | 31 | int m = (l+r)/2; 32 | 33 | if (pos <= m) upd(no*2, l, m, pos, val); 34 | else upd(no*2+1, m+1, r, pos, val); 35 | 36 | tree[no] = max(tree[no*2], tree[no*2+1]); 37 | } 38 | 39 | int get(int no, int l, int r, int a, int b) { 40 | if (a <= l and r <= b) { 41 | return tree[no]; 42 | } 43 | int m = (l+r)/2; 44 | 45 | if (b <= m) return get(no*2, l, m, a, b); 46 | if (a > m) return get(no*2+1, m+1, r, a, b); 47 | 48 | return max( 49 | get(no*2, l, m, a, b), 50 | get(no*2+1, m+1, r, a, b) 51 | ); 52 | } 53 | }; 54 | 55 | struct HLD { 56 | HLD(int n) : seg(n), par(n), d(n), heav(n, -1), head(n), pos(n), cur_pos(0) { 57 | dfs(0); 58 | decompose(0, 0); 59 | } 60 | 61 | int lca(int a, int b) { 62 | for (; head[a] != head[b]; b = par[head[b]]) { 63 | if (d[head[a]] > d[head[b]]) { 64 | swap(a, b); 65 | } 66 | } 67 | if (d[a] > d[b]) { 68 | return b; 69 | } 70 | else return a; 71 | } 72 | 73 | int max_path(int a, int b) { 74 | int res = 0; 75 | for (; head[a] != head[b]; b = par[head[b]]) { 76 | if (d[head[a]] > d[head[b]]) { 77 | swap(a, b); 78 | } 79 | 80 | res = max(res, seg.get(pos[head[b]], pos[b])); 81 | } 82 | if (d[a] > d[b]) { 83 | swap(a, b); 84 | } 85 | res = max(res, seg.get(pos[a], pos[b])); 86 | return res; 87 | } 88 | 89 | void upd(int x, int val) { 90 | seg.upd(pos[x], val); 91 | } 92 | 93 | private: 94 | Seg seg; 95 | vector par, d, heav, head, pos; 96 | int cur_pos; 97 | 98 | int dfs(int x, int p = -1) { 99 | int sz = 1; 100 | int max_c_size = 0; 101 | 102 | for (int u : v[x]) { 103 | if (u == p) continue; 104 | 105 | par[u] = x; 106 | d[u] = d[x] + 1; 107 | 108 | int c_size = dfs(u, x); 109 | sz += c_size; 110 | 111 | if (c_size > max_c_size) { 112 | max_c_size = c_size; 113 | heav[x] = u; 114 | } 115 | } 116 | 117 | return sz; 118 | } 119 | 120 | void decompose(int x, int h) { 121 | head[x] = h; 122 | pos[x] = cur_pos++; 123 | 124 | seg.upd(pos[x], val[x]); 125 | 126 | if (heav[x] != -1) { 127 | decompose(heav[x], h); 128 | } 129 | 130 | for (int u : v[x]) { 131 | if (u == par[x] or u == heav[x]) continue; 132 | decompose(u, u); 133 | } 134 | } 135 | }; 136 | -------------------------------------------------------------------------------- /graph/hungarian.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | constexpr int inf = numeric_limits::max(); 6 | 7 | // finds an answer for the assignment problem using 8 | // the hungarian algorithm in O(n^2*m) [O(n^3)] 9 | // everything is 1 indexed 10 | // ans[0] is the cost of the minimum assignment 11 | struct Hungarian { 12 | Hungarian(vector> const& a) : 13 | n((int)a.size() - 1), m((int)a[0].size() - 1), 14 | u(n+1), v(m+1), p(m+1), way(m+1) 15 | { 16 | for (int i = 1; i <= n; i++) { 17 | p[0] = i; 18 | int j0 = 0; 19 | vector minv (m+1, inf); 20 | vector used (m+1, false); 21 | 22 | do { 23 | used[j0] = true; 24 | int i0 = p[j0], delta = inf, j1; 25 | for (int j = 1; j <= m; j++) { 26 | if (!used[j]) { 27 | int cur = a[i0][j] - u[i0] - v[j]; 28 | if (cur < minv[j]) 29 | minv[j] = cur, way[j] = j0; 30 | if (minv[j] < delta) 31 | delta = minv[j], j1 = j; 32 | } 33 | } 34 | for (int j = 0; j <= m; j++) { 35 | if (used[j]) 36 | u[p[j]] += delta, v[j] -= delta; 37 | else 38 | minv[j] -= delta; 39 | } 40 | j0 = j1; 41 | } while (p[j0] != 0); 42 | 43 | do { 44 | int j1 = way[j0]; 45 | p[j0] = p[j1]; 46 | j0 = j1; 47 | } while (j0); 48 | } 49 | } 50 | 51 | vector get_ans() { 52 | vector ans (n+1); 53 | for (int j=1; j <= m; j++) { 54 | ans[p[j]] = j; 55 | } 56 | ans[0] = -v[0]; 57 | return ans; 58 | } 59 | 60 | private: 61 | int n, m; 62 | vector u, v, p, way; 63 | }; 64 | 65 | int main() { 66 | auto print_ans = [] (auto& h) { 67 | auto res = h.get_ans(); 68 | for (int i = 1; i < (int)res.size(); i++) { 69 | cout << res[i] << " "; 70 | } 71 | cout << "\n"; 72 | }; 73 | 74 | Hungarian h( 75 | {{0, 0, 0, 0, 0}, 76 | {0, 1, 2, 3, 1}, 77 | {0, 1, 2, 3, 1}, 78 | {0, 1, 2, 3, 0}} 79 | ); 80 | 81 | print_ans(h); 82 | } -------------------------------------------------------------------------------- /graph/kruskal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef pair ii; 6 | 7 | const int maxn = 101010; 8 | 9 | template 10 | struct Dsu 11 | { 12 | int pai[size], w[size]; 13 | 14 | int find(int x) 15 | { 16 | if (x == pai[x]) return x; 17 | return pai[x] = find(pai[x]); 18 | } 19 | 20 | void join(int x, int y) 21 | { 22 | x = find(x), y = find(y); 23 | if (x == y) return; 24 | if (w[x] < w[y]) swap(x, y); 25 | pai[y] = x; 26 | w[x] += w[y]; 27 | } 28 | 29 | void clear() 30 | { 31 | for (int i = 0; i < size; i++) 32 | pai[i] = i, w[i] = 1; 33 | } 34 | }; 35 | 36 | struct Edge 37 | { 38 | int a, b, w; 39 | 40 | bool operator<(const Edge& rhs) { 41 | return w < rhs.w; 42 | } 43 | }; 44 | 45 | Dsu dsu; 46 | 47 | int kruskal(vector &lista) 48 | { 49 | dsu.clear(); 50 | sort(lista.begin(), lista.end()); 51 | 52 | int ans = 0; 53 | for (const Edge& ed : lista) { 54 | if (dsu.find(ed.a) == dsu.find(ed.b)) 55 | continue; 56 | dsu.join(ed.a, ed.b); 57 | ans += ed.w; 58 | } 59 | 60 | return ans; 61 | } 62 | 63 | int main() 64 | { 65 | 66 | } -------------------------------------------------------------------------------- /graph/lca_binary_lifting.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int maxn = 101010; 6 | const int maxlog = 20; 7 | 8 | vector v[maxn]; 9 | int dep[maxn]; 10 | int anc[maxn][maxlog]; 11 | 12 | void dfs(int x, int p) 13 | { 14 | for (int u : v[x]) { 15 | if (u == p) continue; 16 | 17 | anc[u][0] = x; 18 | 19 | for (int i = 1; i < maxlog; i++) 20 | anc[u][i] = anc[anc[u][i-1]][i-1]; 21 | 22 | dep[u] = dep[x]+1; 23 | dfs(u, x); 24 | } 25 | } 26 | 27 | int lca(int x, int y) 28 | { 29 | if (x == y) return x; 30 | 31 | if (dep[x] > dep[y]) swap(x, y); 32 | 33 | for (int i = maxlog-1; i >= 0 and dep[x] != dep[y]; i--) 34 | if (dep[y]-(1<= dep[x]) 35 | y = anc[y][i]; 36 | 37 | if (x == y) return x; 38 | for (int i = maxlog-1; i >= 0; i--) 39 | if (anc[x][i] != anc[y][i] and 40 | anc[x][i] != 0 and anc[y][i] != 0) 41 | x = anc[x][i], y = anc[y][i]; 42 | 43 | if (x == y) return x; 44 | return anc[x][0]; 45 | } 46 | 47 | int main() 48 | { 49 | int n; 50 | cin >> n; 51 | 52 | for (int i = 0; i < n-1; i++) { 53 | int a, b; 54 | cin >> a >> b; 55 | 56 | v[a].push_back(b); 57 | v[b].push_back(a); 58 | } 59 | 60 | dfs(1, 1); 61 | 62 | while (1) { 63 | 64 | int x, y; 65 | cin >> x >> y; 66 | 67 | if (x == 0) break; 68 | 69 | int ans = lca(x, y); 70 | cout << ans << "\n"; 71 | } 72 | } -------------------------------------------------------------------------------- /graph/maximum_clique.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int maxn = 20; 6 | 7 | int n, m; 8 | vector v[maxn]; 9 | 10 | int solve(int x, int mask, int cnt) 11 | { 12 | if (x == n+1) return cnt; 13 | 14 | int num = 0; 15 | for (int u : v[x]) { 16 | if (mask&(1<> n >> m; 30 | 31 | for (int i = 0; i < m; i++) { 32 | int a, b; 33 | cin >> a >> b; 34 | 35 | v[a].push_back(b); 36 | v[b].push_back(a); 37 | } 38 | 39 | int ans = solve(1, 0, 0); 40 | 41 | cout << ans << "\n"; 42 | } -------------------------------------------------------------------------------- /graph/strongly_connected.cpp: -------------------------------------------------------------------------------- 1 | struct DirectedDfs { 2 | vector num, low, current, S; 3 | int counter; 4 | vector< vector > scc; 5 | 6 | DirectedDfs() : num(V, -1), low(V, 0), current(V, 0), counter(0) { 7 | REP(i,V) if (num[i] == -1) dfs(i); 8 | } 9 | 10 | void dfs(int u) { 11 | low[u] = num[u] = counter++; 12 | S.push_back(u); 13 | current[u] = 1; 14 | for (auto v : G[u]) { 15 | if (num[v] == -1) dfs(v); 16 | if (current[v]) low[u] = min(low[u], low[v]); 17 | } 18 | if (low[u] == num[u]) { 19 | scc.push_back(vector()); 20 | while (1) { 21 | int v = S.back(); S.pop_back(); current[v] = 0; 22 | scc.back().push_back(v); 23 | if (u == v) break; 24 | } 25 | } 26 | } 27 | }; -------------------------------------------------------------------------------- /graph/union_find.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int maxn = 101010; 6 | 7 | // Disjoint Set Union / Union-Find 8 | template 9 | struct Dsu 10 | { 11 | // parent and weight of subtree i 12 | int pai[size], w[size]; 13 | 14 | // find the superior parent of x 15 | int find(int x) 16 | { 17 | // if x if already the superior parent 18 | if (x == pai[x]) return x; 19 | // compresses the path between x and if superior parent 20 | return pai[x] = find(pai[x]); 21 | } 22 | 23 | // joins the subtree of x and y 24 | void join(int x, int y) 25 | { 26 | // finds the subtree each x and y are part of 27 | x = find(x), y = find(y); 28 | 29 | // if already joined : nothing to do 30 | if (x == y) return; 31 | 32 | // x must have more elements than y in order 33 | // to have the small-to-large preperty 34 | if (w[x] < w[y]) swap(x, y); 35 | 36 | // x becomes the superior parent of y 37 | pai[y] = x; 38 | 39 | // fix weights 40 | w[x] += w[y]; 41 | } 42 | 43 | void clear() 44 | { 45 | // initialize every set x to contain only x 46 | // (empty sets) 47 | for (int i = 0; i < size; i++) 48 | pai[i] = i, w[i] = 1; 49 | } 50 | }; 51 | 52 | Dsu dsu; 53 | 54 | int main() 55 | { 56 | 57 | } -------------------------------------------------------------------------------- /math/bigint.cpp: -------------------------------------------------------------------------------- 1 | // NOTE: 2 | // This code contains various bug fixes compared to the original version from 3 | // indy256 (github.com/indy256/codelibrary/blob/master/cpp/numbertheory/bigint-full.cpp), 4 | // including: 5 | // - Fix overflow bug in mul_karatsuba. 6 | // - Fix overflow bug in fft. 7 | // - Fix bug in initialization from long long. 8 | // - Optimized operators + - *. 9 | // 10 | // Tested: 11 | // - https://www.e-olymp.com/en/problems/266: Comparison 12 | // - https://www.e-olymp.com/en/problems/267: Subtraction 13 | // - https://www.e-olymp.com/en/problems/271: Multiplication 14 | // - https://www.e-olymp.com/en/problems/272: Multiplication 15 | // - https://www.e-olymp.com/en/problems/313: Addition 16 | // - https://www.e-olymp.com/en/problems/314: Addition/Subtraction 17 | // - https://www.e-olymp.com/en/problems/317: Multiplication (simple / karatsuba / fft) 18 | // - https://www.e-olymp.com/en/problems/1327: Multiplication 19 | // - https://www.e-olymp.com/en/problems/1328 20 | // - VOJ BIGNUM: Addition, Subtraction, Multiplication. 21 | // - SGU 111: sqrt 22 | // - SGU 193 23 | // - SPOJ MUL, VFMUL: Multiplication. 24 | // - SPOJ FDIV, VFDIV: Division. 25 | 26 | #include 27 | 28 | using namespace std; 29 | 30 | using ll = long long; 31 | 32 | const int BASE_DIGITS = 9; 33 | const int BASE = 1000000000; 34 | 35 | struct BigInt { 36 | int sign; 37 | vector a; 38 | 39 | // -------------------- Constructors -------------------- 40 | // Default constructor. 41 | BigInt() : sign(1) {} 42 | 43 | // Constructor from long long. 44 | BigInt(long long v) { 45 | *this = v; 46 | } 47 | BigInt& operator = (long long v) { 48 | sign = 1; 49 | if (v < 0) { 50 | sign = -1; 51 | v = -v; 52 | } 53 | a.clear(); 54 | for (; v > 0; v = v / BASE) 55 | a.push_back(v % BASE); 56 | return *this; 57 | } 58 | 59 | // Initialize from string. 60 | BigInt(const string& s) { 61 | read(s); 62 | } 63 | 64 | // -------------------- Input / Output -------------------- 65 | void read(const string& s) { 66 | sign = 1; 67 | a.clear(); 68 | int pos = 0; 69 | while (pos < (int) s.size() && (s[pos] == '-' || s[pos] == '+')) { 70 | if (s[pos] == '-') 71 | sign = -sign; 72 | ++pos; 73 | } 74 | for (int i = s.size() - 1; i >= pos; i -= BASE_DIGITS) { 75 | int x = 0; 76 | for (int j = max(pos, i - BASE_DIGITS + 1); j <= i; j++) 77 | x = x * 10 + s[j] - '0'; 78 | a.push_back(x); 79 | } 80 | trim(); 81 | } 82 | friend istream& operator>>(istream &stream, BigInt &v) { 83 | string s; 84 | stream >> s; 85 | v.read(s); 86 | return stream; 87 | } 88 | 89 | friend ostream& operator<<(ostream &stream, const BigInt &v) { 90 | if (v.sign == -1 && !v.isZero()) 91 | stream << '-'; 92 | stream << (v.a.empty() ? 0 : v.a.back()); 93 | for (int i = (int) v.a.size() - 2; i >= 0; --i) 94 | stream << setw(BASE_DIGITS) << setfill('0') << v.a[i]; 95 | return stream; 96 | } 97 | 98 | // -------------------- Comparison -------------------- 99 | bool operator<(const BigInt &v) const { 100 | if (sign != v.sign) 101 | return sign < v.sign; 102 | if (a.size() != v.a.size()) 103 | return a.size() * sign < v.a.size() * v.sign; 104 | for (int i = ((int) a.size()) - 1; i >= 0; i--) 105 | if (a[i] != v.a[i]) 106 | return a[i] * sign < v.a[i] * sign; 107 | return false; 108 | } 109 | 110 | bool operator>(const BigInt &v) const { 111 | return v < *this; 112 | } 113 | bool operator<=(const BigInt &v) const { 114 | return !(v < *this); 115 | } 116 | bool operator>=(const BigInt &v) const { 117 | return !(*this < v); 118 | } 119 | bool operator==(const BigInt &v) const { 120 | return !(*this < v) && !(v < *this); 121 | } 122 | bool operator!=(const BigInt &v) const { 123 | return *this < v || v < *this; 124 | } 125 | 126 | // Returns: 127 | // 0 if |x| == |y| 128 | // -1 if |x| < |y| 129 | // 1 if |x| > |y| 130 | friend int __compare_abs(const BigInt& x, const BigInt& y) { 131 | if (x.a.size() != y.a.size()) { 132 | return x.a.size() < y.a.size() ? -1 : 1; 133 | } 134 | 135 | for (int i = ((int) x.a.size()) - 1; i >= 0; --i) { 136 | if (x.a[i] != y.a[i]) { 137 | return x.a[i] < y.a[i] ? -1 : 1; 138 | } 139 | } 140 | return 0; 141 | } 142 | 143 | // -------------------- Unary operator - and operators +- -------------------- 144 | BigInt operator-() const { 145 | BigInt res = *this; 146 | if (isZero()) return res; 147 | 148 | res.sign = -sign; 149 | return res; 150 | } 151 | 152 | // Note: sign ignored. 153 | void __internal_add(const BigInt& v) { 154 | if (a.size() < v.a.size()) { 155 | a.resize(v.a.size(), 0); 156 | } 157 | for (int i = 0, carry = 0; i < (int) max(a.size(), v.a.size()) || carry; ++i) { 158 | if (i == (int) a.size()) a.push_back(0); 159 | 160 | a[i] += carry + (i < (int) v.a.size() ? v.a[i] : 0); 161 | carry = a[i] >= BASE; 162 | if (carry) a[i] -= BASE; 163 | } 164 | } 165 | 166 | // Note: sign ignored. 167 | void __internal_sub(const BigInt& v) { 168 | for (int i = 0, carry = 0; i < (int) v.a.size() || carry; ++i) { 169 | a[i] -= carry + (i < (int) v.a.size() ? v.a[i] : 0); 170 | carry = a[i] < 0; 171 | if (carry) a[i] += BASE; 172 | } 173 | this->trim(); 174 | } 175 | 176 | BigInt operator += (const BigInt& v) { 177 | if (sign == v.sign) { 178 | __internal_add(v); 179 | } else { 180 | if (__compare_abs(*this, v) >= 0) { 181 | __internal_sub(v); 182 | } else { 183 | BigInt vv = v; 184 | swap(*this, vv); 185 | __internal_sub(vv); 186 | } 187 | } 188 | return *this; 189 | } 190 | 191 | BigInt operator -= (const BigInt& v) { 192 | if (sign == v.sign) { 193 | if (__compare_abs(*this, v) >= 0) { 194 | __internal_sub(v); 195 | } else { 196 | BigInt vv = v; 197 | swap(*this, vv); 198 | __internal_sub(vv); 199 | this->sign = -this->sign; 200 | } 201 | } else { 202 | __internal_add(v); 203 | } 204 | return *this; 205 | } 206 | 207 | // Optimize operators + and - according to 208 | // https://stackoverflow.com/questions/13166079/move-semantics-and-pass-by-rvalue-reference-in-overloaded-arithmetic 209 | template< typename L, typename R > 210 | typename std::enable_if< 211 | std::is_convertible::value && 212 | std::is_convertible::value && 213 | std::is_lvalue_reference::value, 214 | BigInt>::type friend operator + (L&& l, R&& r) { 215 | BigInt result(std::forward(l)); 216 | result += r; 217 | return result; 218 | } 219 | template< typename L, typename R > 220 | typename std::enable_if< 221 | std::is_convertible::value && 222 | std::is_convertible::value && 223 | std::is_rvalue_reference::value, 224 | BigInt>::type friend operator + (L&& l, R&& r) { 225 | BigInt result(std::move(r)); 226 | result += l; 227 | return result; 228 | } 229 | 230 | template< typename L, typename R > 231 | typename std::enable_if< 232 | std::is_convertible::value && 233 | std::is_convertible::value, 234 | BigInt>::type friend operator - (L&& l, R&& r) { 235 | BigInt result(std::forward(l)); 236 | result -= r; 237 | return result; 238 | } 239 | 240 | // -------------------- Operators * / % -------------------- 241 | friend pair divmod(const BigInt& a1, const BigInt& b1) { 242 | assert(b1 > 0); // divmod not well-defined for b < 0. 243 | 244 | long long norm = BASE / (b1.a.back() + 1); 245 | BigInt a = a1.abs() * norm; 246 | BigInt b = b1.abs() * norm; 247 | BigInt q = 0, r = 0; 248 | q.a.resize(a.a.size()); 249 | 250 | for (int i = a.a.size() - 1; i >= 0; i--) { 251 | r *= BASE; 252 | r += a.a[i]; 253 | long long s1 = r.a.size() <= b.a.size() ? 0 : r.a[b.a.size()]; 254 | long long s2 = r.a.size() <= b.a.size() - 1 ? 0 : r.a[b.a.size() - 1]; 255 | long long d = ((long long) BASE * s1 + s2) / b.a.back(); 256 | r -= b * d; 257 | while (r < 0) { 258 | r += b, --d; 259 | } 260 | q.a[i] = d; 261 | } 262 | 263 | q.sign = a1.sign * b1.sign; 264 | r.sign = a1.sign; 265 | q.trim(); 266 | r.trim(); 267 | auto res = make_pair(q, r / norm); 268 | if (res.second < 0) res.second += b1; 269 | return res; 270 | } 271 | BigInt operator/(const BigInt &v) const { 272 | return divmod(*this, v).first; 273 | } 274 | 275 | BigInt operator%(const BigInt &v) const { 276 | return divmod(*this, v).second; 277 | } 278 | 279 | void operator/=(int v) { 280 | assert(v > 0); // operator / not well-defined for v <= 0. 281 | if (llabs(v) >= BASE) { 282 | *this /= BigInt(v); 283 | return ; 284 | } 285 | if (v < 0) 286 | sign = -sign, v = -v; 287 | for (int i = (int) a.size() - 1, rem = 0; i >= 0; --i) { 288 | long long cur = a[i] + rem * (long long) BASE; 289 | a[i] = (int) (cur / v); 290 | rem = (int) (cur % v); 291 | } 292 | trim(); 293 | } 294 | 295 | BigInt operator/(int v) const { 296 | assert(v > 0); // operator / not well-defined for v <= 0. 297 | 298 | if (llabs(v) >= BASE) { 299 | return *this / BigInt(v); 300 | } 301 | BigInt res = *this; 302 | res /= v; 303 | return res; 304 | } 305 | void operator/=(const BigInt &v) { 306 | *this = *this / v; 307 | } 308 | 309 | long long operator%(long long v) const { 310 | assert(v > 0); // operator / not well-defined for v <= 0. 311 | assert(v < BASE); 312 | int m = 0; 313 | for (int i = a.size() - 1; i >= 0; --i) 314 | m = (a[i] + m * (long long) BASE) % v; 315 | return m * sign; 316 | } 317 | 318 | void operator*=(int v) { 319 | if (llabs(v) >= BASE) { 320 | *this *= BigInt(v); 321 | return ; 322 | } 323 | if (v < 0) 324 | sign = -sign, v = -v; 325 | for (int i = 0, carry = 0; i < (int) a.size() || carry; ++i) { 326 | if (i == (int) a.size()) 327 | a.push_back(0); 328 | long long cur = a[i] * (long long) v + carry; 329 | carry = (int) (cur / BASE); 330 | a[i] = (int) (cur % BASE); 331 | //asm("divl %%ecx" : "=a"(carry), "=d"(a[i]) : "A"(cur), "c"(base)); 332 | /* 333 | int val; 334 | __asm { 335 | lea esi, cur 336 | mov eax, [esi] 337 | mov edx, [esi+4] 338 | mov ecx, base 339 | div ecx 340 | mov carry, eax 341 | mov val, edx; 342 | } 343 | a[i] = val; 344 | */ 345 | } 346 | trim(); 347 | } 348 | 349 | BigInt operator*(int v) const { 350 | if (llabs(v) >= BASE) { 351 | return *this * BigInt(v); 352 | } 353 | BigInt res = *this; 354 | res *= v; 355 | return res; 356 | } 357 | 358 | // Convert BASE 10^old --> 10^new. 359 | static vector convert_base(const vector &a, int old_digits, int new_digits) { 360 | vector p(max(old_digits, new_digits) + 1); 361 | p[0] = 1; 362 | for (int i = 1; i < (int) p.size(); i++) 363 | p[i] = p[i - 1] * 10; 364 | vector res; 365 | long long cur = 0; 366 | int cur_digits = 0; 367 | for (int i = 0; i < (int) a.size(); i++) { 368 | cur += a[i] * p[cur_digits]; 369 | cur_digits += old_digits; 370 | while (cur_digits >= new_digits) { 371 | res.push_back((long long)(cur % p[new_digits])); 372 | cur /= p[new_digits]; 373 | cur_digits -= new_digits; 374 | } 375 | } 376 | res.push_back((int) cur); 377 | while (!res.empty() && !res.back()) 378 | res.pop_back(); 379 | return res; 380 | } 381 | 382 | void fft(vector > & a, bool invert) const { 383 | int n = (int) a.size(); 384 | 385 | for (int i = 1, j = 0; i < n; ++i) { 386 | int bit = n >> 1; 387 | for (; j >= bit; bit >>= 1) 388 | j -= bit; 389 | j += bit; 390 | if (i < j) 391 | swap(a[i], a[j]); 392 | } 393 | 394 | for (int len = 2; len <= n; len <<= 1) { 395 | double ang = 2 * 3.14159265358979323846 / len * (invert ? -1 : 1); 396 | complex wlen(cos(ang), sin(ang)); 397 | for (int i = 0; i < n; i += len) { 398 | complex w(1); 399 | for (int j = 0; j < len / 2; ++j) { 400 | complex u = a[i + j]; 401 | complex v = a[i + j + len / 2] * w; 402 | a[i + j] = u + v; 403 | a[i + j + len / 2] = u - v; 404 | w *= wlen; 405 | } 406 | } 407 | } 408 | if (invert) 409 | for (int i = 0; i < n; ++i) 410 | a[i] /= n; 411 | } 412 | 413 | void multiply_fft(const vector &a, const vector &b, vector &res) const { 414 | vector > fa(a.begin(), a.end()); 415 | vector > fb(b.begin(), b.end()); 416 | int n = 1; 417 | while (n < (int) max(a.size(), b.size())) 418 | n <<= 1; 419 | n <<= 1; 420 | fa.resize(n); 421 | fb.resize(n); 422 | 423 | fft(fa, false); 424 | fft(fb, false); 425 | for (int i = 0; i < n; ++i) 426 | fa[i] *= fb[i]; 427 | fft(fa, true); 428 | 429 | res.resize(n); 430 | long long carry = 0; 431 | for (int i = 0; i < n; ++i) { 432 | long long t = (long long) (fa[i].real() + 0.5) + carry; 433 | carry = t / 1000; 434 | res[i] = t % 1000; 435 | } 436 | } 437 | 438 | BigInt mul_simple(const BigInt &v) const { 439 | BigInt res; 440 | res.sign = sign * v.sign; 441 | res.a.resize(a.size() + v.a.size()); 442 | for (int i = 0; i < (int) a.size(); ++i) 443 | if (a[i]) 444 | for (int j = 0, carry = 0; j < (int) v.a.size() || carry; ++j) { 445 | long long cur = res.a[i + j] + (long long) a[i] * (j < (int) v.a.size() ? v.a[j] : 0) + carry; 446 | carry = (int) (cur / BASE); 447 | res.a[i + j] = (int) (cur % BASE); 448 | } 449 | res.trim(); 450 | return res; 451 | } 452 | 453 | typedef vector vll; 454 | 455 | static vll karatsubaMultiply(const vll &a, const vll &b) { 456 | int n = a.size(); 457 | vll res(n + n); 458 | if (n <= 32) { 459 | for (int i = 0; i < n; i++) 460 | for (int j = 0; j < n; j++) 461 | res[i + j] += a[i] * b[j]; 462 | return res; 463 | } 464 | 465 | int k = n >> 1; 466 | vll a1(a.begin(), a.begin() + k); 467 | vll a2(a.begin() + k, a.end()); 468 | vll b1(b.begin(), b.begin() + k); 469 | vll b2(b.begin() + k, b.end()); 470 | 471 | vll a1b1 = karatsubaMultiply(a1, b1); 472 | vll a2b2 = karatsubaMultiply(a2, b2); 473 | 474 | for (int i = 0; i < k; i++) 475 | a2[i] += a1[i]; 476 | for (int i = 0; i < k; i++) 477 | b2[i] += b1[i]; 478 | 479 | vll r = karatsubaMultiply(a2, b2); 480 | for (int i = 0; i < (int) a1b1.size(); i++) 481 | r[i] -= a1b1[i]; 482 | for (int i = 0; i < (int) a2b2.size(); i++) 483 | r[i] -= a2b2[i]; 484 | 485 | for (int i = 0; i < (int) r.size(); i++) 486 | res[i + k] += r[i]; 487 | for (int i = 0; i < (int) a1b1.size(); i++) 488 | res[i] += a1b1[i]; 489 | for (int i = 0; i < (int) a2b2.size(); i++) 490 | res[i + n] += a2b2[i]; 491 | return res; 492 | } 493 | 494 | BigInt mul_karatsuba(const BigInt &v) const { 495 | vector a6 = convert_base(this->a, BASE_DIGITS, 6); 496 | vector b6 = convert_base(v.a, BASE_DIGITS, 6); 497 | vll a(a6.begin(), a6.end()); 498 | vll b(b6.begin(), b6.end()); 499 | while (a.size() < b.size()) 500 | a.push_back(0); 501 | while (b.size() < a.size()) 502 | b.push_back(0); 503 | while (a.size() & (a.size() - 1)) 504 | a.push_back(0), b.push_back(0); 505 | vll c = karatsubaMultiply(a, b); 506 | BigInt res; 507 | res.sign = sign * v.sign; 508 | long long carry = 0; 509 | for (int i = 0; i < (int) c.size(); i++) { 510 | long long cur = c[i] + carry; 511 | res.a.push_back((int) (cur % 1000000)); 512 | carry = cur / 1000000; 513 | } 514 | res.a = convert_base(res.a, 6, BASE_DIGITS); 515 | res.trim(); 516 | return res; 517 | } 518 | 519 | void operator*=(const BigInt &v) { 520 | *this = *this * v; 521 | } 522 | BigInt operator*(const BigInt &v) const { 523 | if (a.size() * v.a.size() <= 1000111) return mul_simple(v); 524 | if (a.size() > 500111 || v.a.size() > 500111) return mul_fft(v); 525 | return mul_karatsuba(v); 526 | } 527 | 528 | BigInt mul_fft(const BigInt& v) const { 529 | BigInt res; 530 | res.sign = sign * v.sign; 531 | multiply_fft(convert_base(a, BASE_DIGITS, 3), convert_base(v.a, BASE_DIGITS, 3), res.a); 532 | res.a = convert_base(res.a, 3, BASE_DIGITS); 533 | res.trim(); 534 | return res; 535 | } 536 | 537 | // -------------------- Misc -------------------- 538 | BigInt abs() const { 539 | BigInt res = *this; 540 | res.sign *= res.sign; 541 | return res; 542 | } 543 | void trim() { 544 | while (!a.empty() && !a.back()) 545 | a.pop_back(); 546 | if (a.empty()) 547 | sign = 1; 548 | } 549 | 550 | bool isZero() const { 551 | return a.empty() || (a.size() == 1 && !a[0]); 552 | } 553 | 554 | friend BigInt gcd(const BigInt &a, const BigInt &b) { 555 | return b.isZero() ? a : gcd(b, a % b); 556 | } 557 | friend BigInt lcm(const BigInt &a, const BigInt &b) { 558 | return a / gcd(a, b) * b; 559 | } 560 | 561 | friend BigInt sqrt(const BigInt &a1) { 562 | BigInt a = a1; 563 | while (a.a.empty() || a.a.size() % 2 == 1) 564 | a.a.push_back(0); 565 | 566 | int n = a.a.size(); 567 | 568 | int firstDigit = (int) sqrt((double) a.a[n - 1] * BASE + a.a[n - 2]); 569 | int norm = BASE / (firstDigit + 1); 570 | a *= norm; 571 | a *= norm; 572 | while (a.a.empty() || a.a.size() % 2 == 1) 573 | a.a.push_back(0); 574 | 575 | BigInt r = (long long) a.a[n - 1] * BASE + a.a[n - 2]; 576 | firstDigit = (int) sqrt((double) a.a[n - 1] * BASE + a.a[n - 2]); 577 | int q = firstDigit; 578 | BigInt res; 579 | 580 | for(int j = n / 2 - 1; j >= 0; j--) { 581 | for(; ; --q) { 582 | BigInt r1 = (r - (res * 2 * BigInt(BASE) + q) * q) * BigInt(BASE) * BigInt(BASE) + (j > 0 ? (long long) a.a[2 * j - 1] * BASE + a.a[2 * j - 2] : 0); 583 | if (r1 >= 0) { 584 | r = r1; 585 | break; 586 | } 587 | } 588 | res *= BASE; 589 | res += q; 590 | 591 | if (j > 0) { 592 | int d1 = res.a.size() + 2 < r.a.size() ? r.a[res.a.size() + 2] : 0; 593 | int d2 = res.a.size() + 1 < r.a.size() ? r.a[res.a.size() + 1] : 0; 594 | int d3 = res.a.size() < r.a.size() ? r.a[res.a.size()] : 0; 595 | q = ((long long) d1 * BASE * BASE + (long long) d2 * BASE + d3) / (firstDigit * 2); 596 | } 597 | } 598 | 599 | res.trim(); 600 | return res / norm; 601 | } 602 | }; 603 | 604 | bool is_sqrt(BigInt n) { 605 | static constexpr int primes[] = {3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149}; 606 | 607 | auto fexp = [] (ll a, ll b, ll c) { 608 | ll ans= 1; 609 | while (b) { 610 | if (b&1) ans = a*ans%c; 611 | a = a*a%c; 612 | b /= 2; 613 | } 614 | return ans; 615 | }; 616 | 617 | for (int p : primes) { 618 | ll x = n % p; 619 | 620 | if (x == 0) continue; 621 | 622 | if (fexp(x, (p-1)/2, p) != 1) return false; 623 | } 624 | 625 | return true; 626 | } 627 | -------------------------------------------------------------------------------- /math/binary_gcd.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // important! 4 | #pragma GCC target("bmi") 5 | 6 | template 7 | T gcd(T a, T b) { 8 | auto ctz = [] (T const& x) { return __builtin_ctzll(x); }; 9 | 10 | int shift = ctz(a|b); 11 | b >>= ctz(b); 12 | 13 | while (a) { 14 | a >>= ctz(a); 15 | if (a < b) std::swap(a, b); 16 | a -= b; 17 | } 18 | 19 | return b << shift; 20 | } 21 | 22 | int main() { 23 | using ll = uint64_t; 24 | 25 | ll a, b; 26 | std::cin >> a >> b; 27 | 28 | std::cout << gcd(a, b) << "\n"; 29 | } -------------------------------------------------------------------------------- /math/binary_perm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // generates next integer w with popcount(w) == popcount(v) 6 | uint32_t next_perm(uint32_t v) { 7 | uint32_t t = (v | ( v - 1)) + 1; 8 | uint32_t w = t | ((((t & -t) / (v & -v)) >> 1) - 1); 9 | return w; 10 | } 11 | 12 | int main() { 13 | int n; 14 | cin >> n; 15 | 16 | // loop throught all the permutations with 1, 2, 3... bits set 17 | for (int i = 1; i < n; i++) { 18 | for (int x = (1<(x) << "\n"; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /math/brent.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | template 6 | tuple brent(T const& v) { 7 | int power = 1; 8 | int lam = 1; 9 | auto tortoise = v, hare = next(v); 10 | 11 | while (tortoise != hare) { 12 | if (power == lam) { 13 | tortoise = hare; 14 | power *= 2; 15 | lam = 0; 16 | } 17 | hare = next(hare); 18 | lam++; 19 | } 20 | 21 | int it = 0; 22 | tortoise = hare = v; 23 | for (int i = 0; i < lam; i++) { 24 | hare = next(hare); 25 | } 26 | // now hare has walked lambda distance 27 | 28 | int mu = 0; 29 | tortoise = v; 30 | while (tortoise != hare) { 31 | tortoise = next(tortoise); 32 | hare = next(hare); 33 | mu++; 34 | } 35 | // hare has walked lambda+mu and 36 | // tortoise has walked mu 37 | // they meet at start of cycle 38 | 39 | // lenght outside of cycle and cycle lenght 40 | return {mu, lam}; 41 | } 42 | -------------------------------------------------------------------------------- /math/carmichael.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using namespace std; 6 | 7 | using u128 = __uint128_t; 8 | using s128 = __int128_t; 9 | using u64 = uint64_t; 10 | 11 | inline u128 mul(u128 x, u128 y, u128 c) 12 | { 13 | u128 ans = 0; 14 | static const u64 shift = 25; 15 | while (y) { 16 | ans += x*(y&((1<>= shift; 19 | } 20 | return ans % c; 21 | } 22 | 23 | u128 HI(u128 x) { return x>>64; }; 24 | u128 LO(u128 x) { return u64(x); }; 25 | 26 | namespace Prime { 27 | 28 | int const num_tries = 20; 29 | 30 | u128 power(u128 a, u128 b, u128 c) { 31 | u128 ans = 1; 32 | while (b) { 33 | 34 | if (b&1) ans = mul(ans, a, c); 35 | a = mul(a, a, c); 36 | b >>= 1; 37 | } 38 | return ans; 39 | } 40 | 41 | bool witness(u128 base, u128 s, u128 d, u128 n) { 42 | u128 x = power(base, d, n); 43 | u128 y; 44 | while (s--) { 45 | 46 | y = mul(x, x, n); 47 | if (y == 1 and x != 1 and x != n-1) return false; 48 | x = y; 49 | } 50 | if (x != 1) return false; 51 | return true; 52 | } 53 | 54 | mt19937_64 rd; 55 | 56 | bool is_prime(u128 x) { 57 | if (x == 2 or x == 3 or x == 1) return true; 58 | if (x % 2 == 0 or x % 3 == 0) return false; 59 | 60 | u128 s = 1, d = x>>1; 61 | while (!(d&1)) s++, d>>= 1; 62 | 63 | uniform_int_distribution rng(2, HI(x)? u64(-1ull): (u64(x)-1)); 64 | 65 | for (int i = 0; i < num_tries; i++) { 66 | u64 p = rng(rd); 67 | if (!witness(p, s, d, x)) return false; 68 | } 69 | return true; 70 | } 71 | } //end namespace Prime 72 | 73 | namespace Factor { 74 | 75 | int const num_tries = 10; 76 | 77 | u128 n, niv_n; 78 | void setn(u128 n_) { 79 | // calculates multiplicative inverse of n mod 2^128 80 | // to use in modular reduction (how?) 81 | n = n_; 82 | niv_n = 1; 83 | u128 x = n; 84 | for (int i = 1; i <= 126; i++) 85 | { 86 | niv_n*=x; 87 | x*=x; 88 | } 89 | } 90 | 91 | struct u256 { 92 | u128 hi, lo; 93 | 94 | static u256 mul128(u128 x,u128 y) { 95 | u128 t1 = LO(x)*LO(y); 96 | u128 t2 = HI(x)*LO(y) + HI(y)*LO(x) + HI(t1); 97 | return { HI(x)*HI(y) + HI(t2) , (t2<<64) + LO(t1) }; 98 | } 99 | }; 100 | 101 | u128 mmul(u128 x,u128 y) { 102 | u256 m = u256::mul128(x,y); 103 | // some kind of montgomery reduction? 104 | u128 ans = m.hi - u256::mul128(m.lo*niv_n, n).hi; 105 | if (s128(ans) < 0) ans += n; 106 | return ans; 107 | } 108 | 109 | inline u128 f(u128 x, u128 inc) { 110 | return mmul(x, x) + inc; 111 | } 112 | 113 | inline u128 gcd(u128 a, u128 b) { 114 | auto ctz = [] (u128 x) { 115 | if (!HI(x)) return __builtin_ctzll(x); 116 | return 64 + __builtin_ctzll(x>>64); 117 | }; 118 | 119 | int shift = ctz(a|b); 120 | b >>= ctz(b); 121 | while (a) { 122 | a >>= ctz(a); 123 | if (a < b) swap(a, b); 124 | a -= b; 125 | } 126 | return b << shift; 127 | } 128 | 129 | inline u128 rho(u128 seed, u128 n, u64 inc) { 130 | static const int step=1<<9; 131 | 132 | setn(n); 133 | 134 | auto sub = [&] (u128 x, u128 y) { return x>y ? x-y:y-x; }; 135 | 136 | u128 y = f(seed, inc); 137 | 138 | for (int l=1;; l<<=1) 139 | { 140 | u128 x = y; 141 | for (int i = 1; i <= l; i++) y = f(y, inc); 142 | for (int k = 0; k < l; k += step) 143 | { 144 | int d = min(step, l-k); 145 | u128 g = seed, y0 = y; 146 | 147 | for (int i = 1; i <= d; i++) { 148 | y = f(y, inc); 149 | g = mmul(g, sub(x,y)); 150 | } 151 | 152 | g = gcd(g,n); 153 | 154 | if (g==1) continue; 155 | if (g!=n) return g; 156 | 157 | u128 y = y0; 158 | 159 | while (gcd(sub(x,y), n) == 1) y = f(y, inc); 160 | 161 | return gcd(sub(x,y), n) % n; 162 | } 163 | } 164 | return 0; 165 | } 166 | 167 | mt19937_64 rd; 168 | 169 | u128 rho(u128 x) { 170 | if (x <= 3) return 0; 171 | if (x%2 == 0) return 2; 172 | if (x%3 == 0) return 3; 173 | 174 | uniform_int_distribution rng(2, HI(x)? u64(-1ull): (u64(x)-1)); 175 | 176 | for (u128 i = 2; i < num_tries; i++) { 177 | u128 ans = rho(rng(rd), x, i); 178 | if (ans != 0 and ans != x) return ans; 179 | } 180 | return 0; 181 | } 182 | 183 | void factor(u128 x, vector& primes) { 184 | 185 | if (Prime::is_prime(x)) primes.push_back(x); 186 | else { 187 | u128 fac = rho(x); 188 | factor(fac, primes); 189 | factor(x/fac, primes); 190 | } 191 | } 192 | 193 | vector factor(u128 x) { 194 | vector v; 195 | factor(x, v); 196 | sort(v.begin(), v.end()); 197 | return v; 198 | } 199 | 200 | vector> factor_pairs(u128 x) { 201 | auto v = factor(x); 202 | vector> res; 203 | 204 | for (int i = 0; i < (int)v.size(); i++) { 205 | if (i == 0 or res.back().first != v[i]) 206 | res.emplace_back(v[i], 1); 207 | else 208 | res.back().second++; 209 | } 210 | return res; 211 | } 212 | } // end namespace Factor 213 | 214 | template 215 | void read(T &x) 216 | { 217 | #define gc (c=getchar()) 218 | 219 | char c; 220 | while(gc < '0'); 221 | x = c - '0'; 222 | while(gc >= '0') x = x*10 + c - '0'; 223 | 224 | #undef gc 225 | } 226 | 227 | template 228 | void write(T x, char c = '\n') 229 | { 230 | static char st[40]; 231 | int top=0; 232 | do {st[++top] = '0' + x%10;} while (x /=10); 233 | do {putchar(st[top]);} while (--top); 234 | if (c != 0) putchar(c); 235 | } 236 | 237 | template 238 | T gcd(T a, T b) { 239 | if (b == 0) return a; 240 | return gcd(b, a%b); 241 | } 242 | 243 | template 244 | T lcm(T a, T b) { 245 | return a/gcd(a, b)*b; 246 | } 247 | 248 | template 249 | T power(T a, T b) { 250 | T ans = 1; 251 | while (b) { 252 | if (b&1) ans *= a; 253 | a *= a; 254 | b >>= 1; 255 | } 256 | return ans; 257 | } 258 | 259 | template 260 | T carmichael(pair const& x) { 261 | T ans = power(x.first, x.second-1) * (x.first-1); 262 | return ans; 263 | } 264 | template 265 | T carmichael(T x) { 266 | auto factors = Factor::factor_pairs(x); 267 | T ans = 1; 268 | 269 | for (auto const& i : factors) { 270 | ans = lcm(ans, carmichael(i)); 271 | } 272 | 273 | return ans; 274 | } 275 | 276 | int main() { 277 | u128 x; 278 | read(x); 279 | 280 | write(carmichael(x)); 281 | } -------------------------------------------------------------------------------- /math/choose.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | 7 | const ll mod = 1e9 + 7; 8 | const int maxn = 1e6 + 10; 9 | 10 | ll fac[maxn]; 11 | ll inv[maxn]; 12 | ll invfac[maxn]; 13 | 14 | void init() 15 | { 16 | fac[0] = 1ll; 17 | for (ll i = 1; i < maxn; i++) 18 | fac[i] = fac[i-1] * i % mod; 19 | 20 | inv[1] = 1ll; 21 | for (ll i = 2; i < maxn; i++) 22 | inv[i] = (mod - (mod/i) * inv[mod%i] % mod) % mod; 23 | 24 | invfac[0] = 1ll; 25 | for (ll i = 1; i < maxn; i++) 26 | invfac[i] = invfac[i-1] * inv[i] % mod; 27 | } 28 | 29 | ll choose(int n, int k) 30 | { 31 | return (fac[n] * invfac[k]) % mod * invfac[n-k] % mod; 32 | } 33 | 34 | int main() 35 | { 36 | init(); 37 | 38 | int n, k; 39 | cin >> n >> k; 40 | 41 | cout << choose(n, k) << "\n"; 42 | } 43 | -------------------------------------------------------------------------------- /math/compute_wheel.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | vector compute_wheel(vector const& v) { 6 | int sz = 1; 7 | for (auto x : v) sz *= x; 8 | 9 | vector primes; 10 | 11 | vector s(sz+1); 12 | for (auto i : v) 13 | for (int j = i; j <= sz; j += i) 14 | s[j] = 1; 15 | 16 | for (int i = v.back(); i <= sz; i++) 17 | if (!s[i]) 18 | primes.push_back(i); 19 | 20 | primes.push_back(sz+1); 21 | primes.push_back(primes.front()+sz); 22 | vector inc(primes.size()-1); 23 | 24 | for (int i = 0; i < int(inc.size()); i++) 25 | inc[i] = primes[i+1]-primes[i]; 26 | 27 | return inc; 28 | } 29 | 30 | int main() { 31 | auto x = compute_wheel({2, 3, 5}); 32 | 33 | cout << "{ "; 34 | for (auto i : x) cout << i << ", "; 35 | cout << "}\n"; 36 | } -------------------------------------------------------------------------------- /math/determinant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | template 7 | void divide_row(std::vector &A, T ratio) { 8 | for (auto& num : A) { 9 | num /= ratio; 10 | } 11 | } 12 | 13 | template 14 | void equalize_row(std::vector const& A, std::vector &B, T ratio) { 15 | int32_t n = A.size(); 16 | for (int32_t i = 0; i < n; i++) { 17 | B[i] += A[i]*ratio; 18 | } 19 | } 20 | 21 | template 22 | void print_matrix(std::vector> const& A) { 23 | for (auto const& row : A) { 24 | for (auto const& num : row) { 25 | std::cout << num << " "; 26 | } 27 | std::cout << "\n"; 28 | } 29 | } 30 | 31 | template 32 | T determinant(std::vector> A) { 33 | T ans = 1; 34 | 35 | int32_t n = A.size(); 36 | for (int32_t i = 0; i < n; i++) { 37 | int32_t best = i; 38 | 39 | for (int32_t j = i+1; j < n; j++) { 40 | if (abs(A[best][i]) < abs(A[j][i])) { 41 | best = j; 42 | } 43 | } 44 | 45 | if (best != i) { 46 | ans = -ans; 47 | std::swap(A[best], A[i]); 48 | } 49 | 50 | if (A[i][i] == T()) { 51 | return T(); 52 | } 53 | 54 | ans *= T(A[i][i]); 55 | divide_row(A[i], A[i][i]); 56 | 57 | for (int32_t j = i+1; j < n; j++) { 58 | equalize_row(A[i], A[j], -A[j][i]); 59 | } 60 | } 61 | 62 | for (int32_t i = 0; i < n; i++) { 63 | ans *= A[i][i]; 64 | } 65 | 66 | return ans; 67 | } 68 | 69 | int main() { 70 | using rational = mpq_class; 71 | 72 | int32_t n; 73 | std::cin >> n; 74 | 75 | auto M = std::vector>(n, std::vector(n)); 76 | for (auto& row : M) { 77 | for (auto& x : row) { 78 | std::cin >> x; 79 | } 80 | } 81 | 82 | auto x = determinant(M); 83 | 84 | std::cout << x << "\n"; 85 | } -------------------------------------------------------------------------------- /math/discrete_log.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | 7 | ll mul(ll a, ll b, ll c) 8 | { 9 | return __int128(a)*b%c; 10 | } 11 | 12 | ll power(ll a, ll b, ll c) 13 | { 14 | ll ans = 1; 15 | while (b) { 16 | if (b&1) ans = mul(ans, a, c); 17 | a = mul(a, a, c); 18 | b >>= 1; 19 | } 20 | return ans; 21 | } 22 | 23 | // finds x such that (a^x) % mod == b 24 | ll d_log(ll a, ll b, ll mod) 25 | { 26 | ll m = ll(std::ceil(std::sqrt(mod))); 27 | unordered_map tb; 28 | ll e = 1; 29 | 30 | for (ll i = 0; i < m; i++) { 31 | tb[e] = i; 32 | e = mul(e, a, mod); 33 | } 34 | 35 | ll f = power(a, mod-m-1, mod); 36 | e = b; 37 | 38 | for (ll i = 0; i < m; i++) { 39 | auto it = tb.find(e); 40 | if (it != tb.end()) { 41 | return i*m + it->second; 42 | } 43 | e = mul(e, f, mod); 44 | } 45 | 46 | return -1; 47 | } 48 | 49 | int main() 50 | { 51 | ll a, b, p; 52 | cin >> a >> b >> p; 53 | 54 | cout < 2 | 3 | using namespace std; 4 | 5 | typedef unsigned long long ull; 6 | 7 | int ilog2(ull x) 8 | { 9 | int ans = 0; 10 | if (x&0xffffffff00000000) ans += 32, x >>= 32; 11 | if (x&0xffff0000) ans += 16, x >>= 16; 12 | if (x&0xff00) ans += 8, x >>= 8; 13 | if (x&0xf0) ans += 4, x >>= 4; 14 | if (x&0xc) ans += 2, x >>= 2; 15 | if (x&0x2) ans += 1; 16 | return ans; 17 | } 18 | 19 | int ilog10(ull x) 20 | { 21 | int ans = 0; 22 | if (x >= 1000000000000000ull) ans += 16, x /= 10000000000000000ull; 23 | if (x >= 10000000ull) ans += 8, x /= 100000000ull; 24 | if (x >= 1000ull) ans += 4, x /= 10000ull; 25 | if (x >= 10ull) ans += 2, x /= 100ull; 26 | if (x >= 1ull) ans++; 27 | return ans; 28 | } 29 | 30 | int main() 31 | { 32 | mt19937_64 rd; 33 | int n = 100; 34 | 35 | for (int i = 0; i < n; i++) { 36 | ull x = rd(); 37 | cout << "x = " << x << " (" << hex << x << ")"; 38 | cout << " | ilog2(x) = " << dec << ilog2(x); 39 | cout << " | ilog10(x) = " << ilog10(x) << "\n"; 40 | } 41 | } -------------------------------------------------------------------------------- /math/fast_modcheck.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef unsigned int ui; 6 | typedef unsigned long long ull; 7 | 8 | ui fast_inv(ui a) 9 | { 10 | ui ans = 1, lim = 31; 11 | while (lim--) { 12 | ans = ans*a; 13 | a = a*a; 14 | } 15 | return ans; 16 | } 17 | 18 | ui is_mul(ui a, ui b) 19 | { 20 | ui num = fast_inv(b); 21 | ui lim = -1u/b; 22 | return a*num <= lim; 23 | } 24 | 25 | int main() 26 | { 27 | mt19937 rd{random_device{}()}; 28 | 29 | using uni = uniform_int_distribution; 30 | 31 | cout << is_mul(-1u, 3) << "\n"; 32 | } -------------------------------------------------------------------------------- /math/fast_pollard_rho.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | using u128 = __uint128_t; 6 | using s128 = __int128_t; 7 | using u64 = uint64_t; 8 | 9 | inline u128 mul(u128 x, u128 y, u128 c) 10 | { 11 | u128 ans = 0; 12 | static const u64 shift = 25; 13 | while (y) { 14 | ans += x*(y&(1<>= shift; 17 | } 18 | return ans % c; 19 | } 20 | 21 | u128 HI(u128 x) { return x>>64; }; 22 | u128 LO(u128 x) { return u64(x); }; 23 | 24 | namespace Prime { 25 | 26 | int const num_tries = 20; 27 | 28 | u128 power(u128 a, u128 b, u128 c) { 29 | u128 ans = 1; 30 | while (b) { 31 | 32 | if (b&1) ans = mul(ans, a, c); 33 | a = mul(a, a, c); 34 | b >>= 1; 35 | } 36 | return ans; 37 | } 38 | 39 | bool witness(u128 base, u128 s, u128 d, u128 n) { 40 | u128 x = power(base, d, n); 41 | u128 y; 42 | while (s--) { 43 | 44 | y = mul(x, x, n); 45 | if (y == 1 and x != 1 and x != n-1) return false; 46 | x = y; 47 | } 48 | if (y != 1) return false; 49 | return true; 50 | } 51 | 52 | mt19937_64 rd; 53 | 54 | bool is_prime(u128 x) { 55 | if (x == 2 or x == 3 or x == 1) return true; 56 | if (x % 2 == 0 or x % 3 == 0) return false; 57 | 58 | u128 s = 1, d = x>>1; 59 | while (!(d&1)) s++, d>>= 1; 60 | 61 | uniform_int_distribution rng(2, HI(x)? u64(-1ull): (u64(x)-1)); 62 | 63 | for (int i = 0; i < num_tries; i++) { 64 | u64 p = rng(rd); 65 | if (!witness(p, s, d, x)) return false; 66 | } 67 | return true; 68 | } 69 | } //end namespace Prime 70 | 71 | namespace Factor { 72 | 73 | int const num_tries = 10; 74 | 75 | u128 n, niv_n; 76 | void setn(u128 n_) { 77 | // calculates multiplicative inverse of n mod 2^128 78 | // to use in modular reduction (how?) 79 | n = n_; 80 | niv_n = 1; 81 | u128 x = n; 82 | for (int i = 1; i <= 126; i++) 83 | { 84 | niv_n*=x; 85 | x*=x; 86 | } 87 | } 88 | 89 | struct u256 { 90 | u128 hi, lo; 91 | 92 | static u256 mul128(u128 x,u128 y) { 93 | u128 t1 = LO(x)*LO(y); 94 | u128 t2 = HI(x)*LO(y) + HI(y)*LO(x) + HI(t1); 95 | return { HI(x)*HI(y) + HI(t2) , (t2<<64) + LO(t1) }; 96 | } 97 | }; 98 | 99 | u128 mmul(u128 x,u128 y) { 100 | u256 m = u256::mul128(x,y); 101 | // some kind of montgomery reduction? 102 | u128 ans = m.hi - u256::mul128(m.lo*niv_n, n).hi; 103 | if (s128(ans) < 0) ans += n; 104 | return ans; 105 | } 106 | 107 | inline u128 f(u128 x, u128 inc) { 108 | return mmul(x, x) + inc; 109 | } 110 | 111 | inline u128 gcd(u128 a, u128 b) { 112 | auto ctz = [] (u128 x) { 113 | if (!HI(x)) return __builtin_ctzll(x); 114 | return 64 + __builtin_ctzll(x>>64); 115 | }; 116 | 117 | int shift = ctz(a|b); 118 | b >>= ctz(b); 119 | while (a) { 120 | a >>= ctz(a); 121 | if (a < b) swap(a, b); 122 | a -= b; 123 | } 124 | return b << shift; 125 | } 126 | 127 | inline u128 rho(u128 seed, u128 n, u64 inc) { 128 | static const int step=1<<9; 129 | 130 | setn(n); 131 | 132 | auto sub = [&] (u128 x, u128 y) { return x>y ? x-y:y-x; }; 133 | 134 | u128 y = f(seed, inc), a = f(seed, inc); 135 | 136 | for (int l=1;; l<<=1) 137 | { 138 | u128 x = y; 139 | for (int i = 1; i <= l; i++) y = f(y, inc); 140 | for (int k = 0; k < l; k += step) 141 | { 142 | int d = min(step, l-k); 143 | u128 g = seed, y0 = y; 144 | 145 | for (int i = 1; i <= d; i++) { 146 | y = f(y, inc); 147 | g = mmul(g, sub(x,y)); 148 | } 149 | 150 | g = gcd(g,n); 151 | 152 | if (g==1) continue; 153 | if (g!=n) return g; 154 | 155 | u128 y = y0; 156 | 157 | while (gcd(sub(x,y), n) == 1) y = f(y, inc); 158 | 159 | return gcd(sub(x,y), n) % n; 160 | } 161 | } 162 | return 0; 163 | } 164 | 165 | mt19937_64 rd; 166 | 167 | u128 rho(u128 x) { 168 | if (x <= 3) return 0; 169 | if (x%2 == 0) return 2; 170 | if (x%3 == 0) return 3; 171 | 172 | uniform_int_distribution rng(2, HI(x)? u64(-1ull): (u64(x)-1)); 173 | 174 | for (u128 i = 2; i < num_tries; i++) { 175 | u128 ans = rho(rng(rd), x, i); 176 | if (ans != 0 and ans != x) return ans; 177 | } 178 | return 0; 179 | } 180 | 181 | void factor(u128 x, vector& primes) { 182 | 183 | if (Prime::is_prime(x)) primes.push_back(x); 184 | else { 185 | u128 fac = rho(x); 186 | factor(fac, primes); 187 | factor(x/fac, primes); 188 | } 189 | } 190 | } // end namespace Factor 191 | 192 | template 193 | void read(T &x) 194 | { 195 | #define gc (c=getchar()) 196 | 197 | char c; 198 | while(gc < '0'); 199 | x = c - '0'; 200 | while(gc >= '0') x = x*10 + c - '0'; 201 | 202 | #undef gc 203 | } 204 | 205 | template 206 | void write(T x, char c) 207 | { 208 | static char st[40]; 209 | int top=0; 210 | do {st[++top] = '0' + x%10;} while (x /=10); 211 | do {putchar(st[top]);} while (--top); 212 | if (c != 0) putchar(c); 213 | } 214 | 215 | template 216 | void write(T x) { write(x, 0); } 217 | 218 | int main() 219 | { 220 | while (true) { 221 | u128 x; 222 | read(x); 223 | 224 | if (x == 0) break; 225 | 226 | vector primes; 227 | Factor::factor(x, primes); 228 | 229 | sort(primes.begin(), primes.end()); 230 | 231 | u128 last = primes.front(), cnt = 0; 232 | for (u128 p : primes) { 233 | if (p == last) cnt++; 234 | else { 235 | write(last); 236 | printf("^"); 237 | write(cnt, ' '); 238 | last = p; 239 | cnt = 1; 240 | } 241 | } 242 | 243 | write(last); 244 | printf("^"); 245 | write(cnt, '\n'); 246 | } 247 | } 248 | -------------------------------------------------------------------------------- /math/gcdext.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | 7 | tuple gcdext(ll a, ll b) 8 | { 9 | if (b == 0) 10 | return {1, 0, a}; 11 | int x, y, g; 12 | tie(x, y, g) = gcdext(b, a%b); 13 | return {y, x-(a/b)*y, g}; 14 | } 15 | 16 | ostream& operator<<(ostream& out, const tuple& x) 17 | { 18 | out << "("; 19 | out << get<0>(x) << ", "; 20 | out << get<1>(x) << ", "; 21 | out << get<2>(x) << ")"; 22 | return out; 23 | } 24 | 25 | int main() 26 | { 27 | ll x, y; 28 | cin >> x >> y; 29 | 30 | auto ans = gcdext(x, y); 31 | 32 | cout << ans << "\n"; 33 | } -------------------------------------------------------------------------------- /math/inv.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | 7 | ll mul(ll a, ll b, ll c) 8 | { 9 | return __int128(a)*b%c; 10 | } 11 | 12 | ll power(ll a, ll b, ll c) 13 | { 14 | ll ans = 1; 15 | while (b) { 16 | if (b&1) ans = mul(ans, a, c); 17 | a = mul(a, a, c); 18 | b >>= 1; 19 | } 20 | return ans; 21 | } 22 | 23 | ll inv(ll x, ll mod) 24 | { 25 | return power(x, mod-2, mod); 26 | } 27 | 28 | int main() 29 | { 30 | ll x, mod; 31 | cin >> x >> mod; 32 | 33 | cout << x << " * " << inv(x, mod) << " = " << (x*inv(x, mod)%mod); 34 | cout << " (mod mod)\n"; 35 | } -------------------------------------------------------------------------------- /math/inverse.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | template 7 | void equalize_row(std::vector const& A, std::vector &B, T ratio) { 8 | int32_t n = A.size(); 9 | for (int32_t i = 0; i < n; i++) { 10 | B[i] += ratio*A[i]; 11 | } 12 | } 13 | 14 | template 15 | void divide_row(std::vector &A, T ratio) { 16 | for (T& num : A) { 17 | num /= ratio; 18 | } 19 | } 20 | 21 | template 22 | void print_matrix(std::vector const& A) { 23 | for (auto& row : A) { 24 | for (auto& x : row) { 25 | std::cout << x << " "; 26 | } 27 | std::cout << "\n"; 28 | } 29 | } 30 | 31 | template 32 | std::vector> inverse(std::vector> M) { 33 | int32_t n = M.size(); 34 | 35 | auto R = std::vector>(n, std::vector(n)); 36 | for (int32_t i = 0; i < n; i++) { 37 | R[i][i] = T(1); 38 | } 39 | 40 | for (int32_t i = 0; i < n; i++) { 41 | int32_t best = i; 42 | for (int32_t j = i+1; j < n; j++) { 43 | if (abs(M[best][i]) < abs(M[j][i])) { 44 | best = j; 45 | } 46 | } 47 | if (best != i) { 48 | std::swap(M[i], M[best]); 49 | std::swap(R[i], R[best]); 50 | } 51 | 52 | divide_row(R[i], M[i][i]); 53 | divide_row(M[i], M[i][i]); 54 | 55 | for (int32_t j = i+1; j < n; j++) { 56 | T ratio = -M[j][i]; 57 | equalize_row(M[i], M[j], ratio); 58 | equalize_row(R[i], R[j], ratio); 59 | } 60 | } 61 | 62 | for (int32_t i = n-1; i > 0; i--) { 63 | for (int32_t j = i-1; j >= 0; j--) { 64 | equalize_row(R[i], R[j], -M[j][i]); 65 | equalize_row(M[i], M[j], -M[j][i]); 66 | } 67 | } 68 | 69 | return R; 70 | } 71 | 72 | int main() { 73 | using rational = mpq_class; 74 | 75 | int32_t n; 76 | std::cin >> n; 77 | 78 | auto M = std::vector>(n, std::vector(n)); 79 | for (auto& row : M) { 80 | for (auto& x : row) { 81 | std::cin >> x; 82 | } 83 | } 84 | 85 | auto A = inverse(M); 86 | 87 | print_matrix(A); 88 | } -------------------------------------------------------------------------------- /math/linear_mobius.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int maxn = 10101010; 6 | 7 | int mu[maxn], lp[maxn]; 8 | 9 | void sieve(int n) 10 | { 11 | fill(mu, mu+maxn, -1); 12 | mu[1] = 1; 13 | 14 | vector pr; 15 | for (int i = 2; i <= n; i++) { 16 | if (lp[i] == 0) { 17 | lp[i] = i; 18 | pr.push_back(i); 19 | } 20 | 21 | for (int p : pr) { 22 | if (p > lp[i] or p*i > n) break; 23 | if (i%p == 0) 24 | mu[i*p] = 0; 25 | lp[p*i] = p; 26 | mu[p*i] *= mu[i]; 27 | } 28 | } 29 | } 30 | 31 | int main() 32 | { 33 | int n; 34 | cin >> n; 35 | 36 | sieve(n); 37 | 38 | for (int i = 1; i <= n; i++) 39 | cout << i << " : " << mu[i] << "\n"; 40 | } -------------------------------------------------------------------------------- /math/linear_phi.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int maxn = 10101010; 6 | 7 | int phi[maxn], lp[maxn]; 8 | 9 | void sieve(int n) 10 | { 11 | iota(phi, phi+maxn, 0); 12 | vector pr; 13 | for (int i = 2; i <= n; i++) { 14 | if (lp[i] == 0) { 15 | lp[i] = i; 16 | pr.push_back(i); 17 | } 18 | phi[i]--; 19 | 20 | for (int p : pr) { 21 | if (p > lp[i] or p*i > n) break; 22 | lp[p*i] = p; 23 | phi[p*i] -= phi[p*i]/p; 24 | } 25 | } 26 | } 27 | 28 | int main() 29 | { 30 | int n; 31 | cin >> n; 32 | 33 | sieve(n); 34 | 35 | for (int i = 1; i <= n; i++) 36 | cout << i << " : " << phi[i] << "\n"; 37 | } -------------------------------------------------------------------------------- /math/linear_sieve.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int maxn = 101010101; 6 | 7 | int lp[maxn]; 8 | 9 | vector sieve(int n) 10 | { 11 | vector pr; 12 | for (int i = 2; i <= n; i++) { 13 | if (lp[i] == 0) { 14 | lp[i] = i; 15 | pr.push_back(i); 16 | } 17 | 18 | for (int p : pr) { 19 | if (p > lp[i] or p*i > n) break; 20 | lp[p*i] = p; 21 | } 22 | } 23 | return pr; 24 | } 25 | 26 | int main() 27 | { 28 | int n; 29 | cin >> n; 30 | 31 | auto ans = sieve(n); 32 | 33 | for (int p : ans) 34 | cout << p << " "; 35 | cout << "\n"; 36 | // cout << ans.size() << "\n"; 37 | } -------------------------------------------------------------------------------- /math/linear_sieve_ext.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int maxn = 10101010; 6 | 7 | int cnt[maxn], lp[maxn]; 8 | 9 | void sieve(int n) 10 | { 11 | vector pr; 12 | for (int i = 2; i <= n; i++) { 13 | if (lp[i] == 0) { 14 | cnt[i] = 1; 15 | lp[i] = i; 16 | pr.push_back(i); 17 | } 18 | 19 | for (int p : pr) { 20 | if (p > lp[i] or p*i > n) break; 21 | 22 | lp[p*i] = p; 23 | 24 | if (i%p == 0) { 25 | cnt[i*p] = cnt[i]+1; 26 | } 27 | else { 28 | cnt[i*p] = 1; 29 | } 30 | } 31 | } 32 | } 33 | 34 | int main() 35 | { 36 | int n; 37 | cin >> n; 38 | 39 | sieve(n); 40 | 41 | for (int i = 1; i <= n; i++) 42 | cout << i << " : " << lp[i] << "^" << cnt[i] << "\n"; 43 | } -------------------------------------------------------------------------------- /math/matrix_expo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | 7 | template 8 | struct Matrix { 9 | int v[N][M]; 10 | 11 | static Matrix ones() { 12 | Matrix ans{}; 13 | for (int i = 0; i < N; i++) ans.v[i][i] = 1; 14 | return ans; 15 | } 16 | }; 17 | 18 | template 19 | Matrix operator*(Matrix const& a, Matrix const& b) { 20 | Matrix ans{}; 21 | 22 | for (int i = 0; i < N; i++) { 23 | for (int j = 0; j < P; j++) { 24 | for (int k = 0; k < M; k++) { 25 | add(ans.v[i][j], (ll)a.v[i][k] * b.v[k][j] % mod); 26 | } 27 | } 28 | } 29 | 30 | return ans; 31 | } 32 | 33 | template 34 | Matrix fexp(Matrix a, ll b) { 35 | auto ans = Matrix::ones(); 36 | while (b) { 37 | if (b&1) ans = ans*a; 38 | a = a*a; 39 | b /= 2; 40 | } 41 | return ans; 42 | } 43 | 44 | template 45 | Matrix coeff(vector const& c) { 46 | Matrix ans{}; 47 | for (int i = 0; i < N-1; i++) { 48 | ans.v[i+1][i] = 1; 49 | } 50 | for (int i = 0; i < N; i++) { 51 | ans.v[0][i] = c[i]; 52 | } 53 | return ans; 54 | } 55 | -------------------------------------------------------------------------------- /math/phi.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int maxn = 1010101; 6 | int s[maxn]; 7 | 8 | void sieve_phi() 9 | { 10 | for (int i = 1; i < maxn; i++) 11 | s[i] = i; 12 | 13 | for (int i = 2; i < maxn; i++) 14 | if (s[i] == i) 15 | for (int j = i; j < maxn; j += i) 16 | s[j] -= s[j]/i; 17 | } 18 | 19 | int phi(int x) 20 | { 21 | int ans = x, k = x; 22 | for (int i = 2; i*i <= x and k > 1; i++) { 23 | if (k%i ==0) { 24 | ans -= ans/i; 25 | while (k%i == 0) 26 | k /= i; 27 | } 28 | } 29 | 30 | if (k != 1) 31 | ans -= ans/k; 32 | 33 | return ans; 34 | } 35 | 36 | int main() 37 | { 38 | sieve_phi(); 39 | } -------------------------------------------------------------------------------- /math/pisano.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ff first 4 | #define ss second 5 | 6 | using namespace std; 7 | 8 | typedef long long ll; 9 | typedef pair ii; 10 | 11 | ll mod; 12 | 13 | struct mat 14 | { 15 | ll a, b, c, d; 16 | 17 | mat& operator*=(const mat& rhs) 18 | { 19 | mat tmp; 20 | tmp.a = (a*rhs.a + b*rhs.c)%mod; 21 | tmp.b = (a*rhs.b + b*rhs.d)%mod; 22 | tmp.c = (c*rhs.a + d*rhs.c)%mod; 23 | tmp.d = (c*rhs.b + d*rhs.d)%mod; 24 | *this = tmp; 25 | return *this; 26 | } 27 | }; 28 | 29 | mat power(mat a, ll b) 30 | { 31 | mat ans = {1, 0, 0, 1}; 32 | while (b) { 33 | 34 | if (b&1) ans *= a; 35 | a *= a; 36 | b >>= 1; 37 | } 38 | return ans; 39 | } 40 | 41 | ii fib(ll x, ll m) 42 | { 43 | mod = m; 44 | mat ans = power({1, 1, 1, 0}, x); 45 | return {ans.b, ans.a}; 46 | } 47 | 48 | ll pis(ll x) 49 | { 50 | if (x <= 5) { 51 | 52 | return vector{0, 1, 3, 8, 6, 20}[x]; 53 | } 54 | 55 | ll num; 56 | 57 | if (x % 5 == 1 or x % 5 == 4) num = x-1; 58 | else num = 2*x+2; 59 | 60 | vector div; 61 | for (ll i = 1; i < sqrt(num); i++) 62 | if (num % i == 0) 63 | div.push_back(i), div.push_back(num/i); 64 | 65 | if (num % int(sqrt(num)) == 0) 66 | div.push_back(int(sqrt(num))); 67 | 68 | sort(div.begin(), div.end()); 69 | 70 | for (ll i : div) 71 | if (fib(i, x) == ii(0, 1)) 72 | return i; 73 | return num; 74 | } 75 | 76 | ll gcd(ll a, ll b) 77 | { 78 | if (b == 0) return a; 79 | return gcd(b, a%b); 80 | } 81 | 82 | ll lcm(ll a, ll b) 83 | { 84 | return __int128(a)*b/gcd(a, b); 85 | } 86 | 87 | ll power(ll a, ll b) 88 | { 89 | ll ans = 1; 90 | while (b) { 91 | 92 | if (b&1) ans *= a; 93 | a *= a; 94 | b >>= 1; 95 | } 96 | return ans; 97 | } 98 | 99 | int main() 100 | { 101 | ios_base::sync_with_stdio(false); 102 | cin.tie(0); 103 | 104 | ll n; 105 | cin >> n; 106 | 107 | ll nn = n; 108 | 109 | vector primes; 110 | ll sqt = sqrt(n); 111 | for (ll i = 2; i <= sqt; i++) { 112 | 113 | if (n%i == 0) { 114 | primes.push_back({i, 1}); 115 | n /= i; 116 | while (n % i == 0) 117 | primes.back().ss++, n/=i; 118 | } 119 | } 120 | if (n != 1) 121 | primes.push_back({n, 1}); 122 | 123 | n = nn; 124 | 125 | ll ans = 1; 126 | 127 | for (auto x : primes) { 128 | 129 | ll tmp = power(x.ff, x.ss-1); 130 | tmp *= pis(x.ff); 131 | 132 | ans = lcm(ans, tmp); 133 | } 134 | 135 | cout << ans << "\n"; 136 | } -------------------------------------------------------------------------------- /math/pollard_rho.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef unsigned long long ll; 6 | 7 | inline ll mul(ll a, ll b, ll c) 8 | { 9 | #ifdef __SIZEOF_INT128__ 10 | return (__uint128_t)a*b%c; 11 | #else 12 | ll ans = 0; 13 | while (b) { 14 | if (b&1) ans = (a+ans)%c; 15 | a = (a+a)%c; 16 | b >>= 1; 17 | } 18 | return ans; 19 | #endif 20 | } 21 | 22 | namespace Prime { 23 | 24 | ll power(ll a, ll b, ll c) { 25 | ll ans = 1; 26 | while (b) { 27 | 28 | if (b&1) ans = mul(ans, a, c); 29 | a = mul(a, a, c); 30 | b >>= 1; 31 | } 32 | return ans; 33 | } 34 | 35 | bool witness(ll base, ll s, ll d, ll n) { 36 | ll x = power(base, d, n); 37 | ll y; 38 | while (s--) { 39 | y = mul(x, x, n); 40 | if (y == 1 and x != 1 and x != n-1) return false; 41 | x = y; 42 | } 43 | if (y != 1) return false; 44 | return true; 45 | } 46 | 47 | ll primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23}; 48 | 49 | bool is_prime(ll x) { 50 | if (x == 2 or x == 3 or x == 1) return true; 51 | if (x % 2 == 0 or x % 3 == 0) return false; 52 | 53 | ll s = 1, d = x>>1; 54 | while (!(d&1)) s++, d>>= 1; 55 | 56 | for (ll p : primes) { 57 | if (p == x) return true; 58 | if (!witness(p, s, d, x)) return false; 59 | } 60 | return true; 61 | } 62 | } //end namespace Prime 63 | 64 | namespace Factor { 65 | 66 | int const num_tries = 10; 67 | 68 | inline ll f(ll x, ll p, ll inc) { 69 | return (mul(x, x, p) + inc) % p; 70 | } 71 | 72 | inline ll gcdd(ll a, ll b) { 73 | while (b) { 74 | a = a%b; 75 | swap(a, b); 76 | } 77 | return a; 78 | } 79 | 80 | inline ll rho(ll seed, ll p, ll inc) { 81 | ll x = seed, y = seed, d = 1; 82 | while (d == 1) { 83 | x = f(x, p, inc); 84 | y = f(f(y, p, inc), p, inc); 85 | d = gcdd(llabs(x-y), p); 86 | } 87 | 88 | if (d == p) return 0; 89 | return d; 90 | } 91 | 92 | mt19937_64 rd; 93 | 94 | ll rho(ll x) { 95 | if (x%2 == 0) return 2; 96 | if (x%3 == 0) return 3; 97 | 98 | uniform_int_distribution rng(2, x-1); 99 | 100 | for (ll i = 2; i < num_tries; i++) { 101 | ll ans = rho(rng(rd), x, i); 102 | if (ans != 0 and ans != x) return ans; 103 | } 104 | return 0; 105 | } 106 | 107 | void factor(vector& v, ll x) { 108 | if (Prime::is_prime(x)) v.push_back(x); 109 | else { 110 | ll y = rho(x); 111 | factor(v, y); 112 | factor(v, x/y); 113 | } 114 | } 115 | } // end namespace Factor 116 | 117 | int main() 118 | { 119 | ll x; 120 | cin >> x; 121 | 122 | vector fac; 123 | 124 | Factor::factor(fac, x); 125 | for (ll i : fac) cout << i << " "; 126 | cout << "\n"; 127 | } -------------------------------------------------------------------------------- /math/prime_count.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | using ll = long long; 6 | 7 | ll isqrt(ll x) { 8 | ll l = 0, r = 1e9; 9 | while (r-l > 1) { 10 | ll m = (l+r)/2; 11 | if (m*m <= x) l = m; 12 | else r = m; 13 | } 14 | return l; 15 | } 16 | 17 | ll icbrt(ll x) { 18 | ll l = 0, r = 1e6; 19 | while (r-l > 1) { 20 | ll m = (l+r)/2; 21 | if (m*m*m <= x) l = m; 22 | else r = m; 23 | } 24 | return l; 25 | } 26 | 27 | vector sieve(int n) { 28 | vector b(n+1); 29 | for (int i = 3; i*i <= n; i += 2) { 30 | if (b[i] == 0) { 31 | for (int j = i*i; j <= n; j += 2*i) { 32 | b[j] = 1; 33 | } 34 | } 35 | } 36 | 37 | vector primes = {2}; 38 | for (int i = 3; i <= n; i += 2) { 39 | if (b[i] == 0) primes.push_back(i); 40 | } 41 | return primes; 42 | } 43 | 44 | // at least sqrt(n) for pi(n) 45 | // bigger values may be faster 46 | // for values up to 1e12 the fastest is around 1e8 47 | // for values up to 1e11 the fastest is around 3e7 48 | int const sqrt_limit = 30000000; 49 | 50 | auto primes = sieve(sqrt_limit); 51 | 52 | using ii = pair; 53 | 54 | // at least pi(sqrt(sqrt(n))) 55 | unordered_map phi_cache[200]; 56 | 57 | ll phi(ll x, int a) { 58 | if (a == 1) { 59 | return (x+1)/2; 60 | } 61 | 62 | if (phi_cache[a].count(x)) { 63 | return phi_cache[a][x]; 64 | } 65 | 66 | ll res = phi(x, a-1) - phi(x / primes[a-1], a-1); 67 | phi_cache[a][x] = res; 68 | 69 | return res; 70 | } 71 | 72 | unordered_map pi_cache; 73 | 74 | ll pi(ll x) { 75 | if (pi_cache.count(x)) return pi_cache[x]; 76 | 77 | if (x < sqrt_limit) { 78 | return upper_bound(primes.begin(), primes.end(), x) - primes.begin(); 79 | } 80 | 81 | ll a = pi(isqrt(isqrt(x))); 82 | ll b = pi(isqrt(x)); 83 | ll c = pi(icbrt(x)); 84 | 85 | ll res = phi(x, a) + (b+a-2)*(b-a+1)/2; 86 | 87 | for (ll i = a+1; i <= b; i++) { 88 | ll w = x / primes[i-1]; 89 | ll b_i = pi(isqrt(w)); 90 | res -= pi(w); 91 | 92 | if (i <= c) { 93 | for (ll j = i; j <= b_i; j++) { 94 | res -= pi(w / primes[j-1]) - j + 1; 95 | } 96 | } 97 | } 98 | 99 | pi_cache[x] = res; 100 | return res; 101 | } 102 | 103 | int main() { 104 | ll n; 105 | cin >> n; 106 | 107 | cout << pi(n) << "\n"; 108 | } -------------------------------------------------------------------------------- /math/rabin_miller.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | 7 | inline ll mul(ll a, ll b, ll c) 8 | { 9 | return __int128(a)*b%c; 10 | } 11 | 12 | inline ll power(ll a, ll b, ll c) 13 | { 14 | ll res = 1; 15 | while(b) { 16 | 17 | if (b&1) res = mul(res, a, c); 18 | a = mul(a, a, c); 19 | b >>= 1; 20 | } 21 | return res; 22 | } 23 | 24 | inline bool witness(ll a, ll d, ll s, ll n) 25 | { 26 | ll x = power(a, d, n), y; 27 | 28 | while (s--) { 29 | 30 | y = mul(x, x, n); 31 | 32 | if (y == 1 and x != 1 and x != n-1) return false; 33 | 34 | x = y; 35 | } 36 | 37 | if (y != 1) return false; 38 | return true; 39 | } 40 | 41 | ll primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23}; 42 | 43 | inline bool is_prime(ll n) 44 | { 45 | if (n == 2 or n == 3) return true; 46 | if (n%2 == 0 or n%3 == 0) return false; 47 | 48 | ll s = __builtin_ctzll(n-1), d = (n-1)>>s; 49 | 50 | for (ll p : primes) { 51 | 52 | if (n == p) return true; 53 | if (!witness(p, d, s, n)) return false; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | int main() 60 | { 61 | ll x; 62 | cin >> x; 63 | 64 | cout << boolalpha << is_prime(x) << "\n"; 65 | } -------------------------------------------------------------------------------- /math/rabin_miller_bench.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef long long ll; 6 | 7 | inline ll mul(ll a, ll b, ll c) 8 | { 9 | return __int128(a)*b%c; 10 | } 11 | 12 | inline ll power(ll a, ll b, ll c) 13 | { 14 | ll res = 1; 15 | while(b) { 16 | 17 | if (b&1) res = mul(res, a, c); 18 | a = mul(a, a, c); 19 | b >>= 1; 20 | } 21 | return res; 22 | } 23 | 24 | inline bool witness(ll a, ll d, ll s, ll n) 25 | { 26 | ll x = power(a, d, n), y; 27 | 28 | while (s--) { 29 | 30 | y = mul(x, x, n); 31 | 32 | if (y == 1 and x != 1 and x != n-1) return false; 33 | 34 | x = y; 35 | } 36 | 37 | if (y != 1) return false; 38 | return true; 39 | } 40 | 41 | ll primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23}; 42 | 43 | inline bool is_prime(ll n) 44 | { 45 | if (n == 2 or n == 3) return true; 46 | if (n%2 == 0 or n%3 == 0) return false; 47 | 48 | ll s = 1, d = n/2; 49 | while (d%2 == 0) 50 | s++, d /= 2; 51 | 52 | for (ll p : primes) { 53 | 54 | if (n == p) return true; 55 | if (!witness(p, d, s, n)) return false; 56 | } 57 | 58 | return true; 59 | } 60 | 61 | struct seeder 62 | { 63 | template 64 | void generate(T begin, T end) 65 | { 66 | for (random_device r; begin != end; ++begin) 67 | *begin = r(); 68 | } 69 | }; 70 | 71 | using test_func = bool (*)(ll); 72 | using init_func = vector (*)(test_func, int); 73 | 74 | int test(string_view test_name, test_func func, init_func init_vector, int iters) 75 | { 76 | auto v = init_vector(func, iters); 77 | 78 | auto timer = chrono::steady_clock::now(); 79 | 80 | int ans = 0; 81 | for (ll x : v) 82 | ans += func(x); 83 | 84 | auto fim = (chrono::steady_clock::now()-timer).count()/1000000.0; 85 | cout << test_name << "\n"; 86 | cout << ans << " / " << iters << "\n"; 87 | cout << fim << "ms" <<"\n\n"; 88 | 89 | return ans; 90 | } 91 | 92 | int main(int argc, char** argv) 93 | { 94 | int num_iters = 100000; 95 | 96 | if (argc > 1) num_iters = stoi(argv[1]); 97 | 98 | auto init_random_vector = [](test_func pr, int sz) -> vector 99 | { 100 | seeder s; 101 | mt19937_64 rd{s}; 102 | uniform_int_distribution rng(2, 3'000'000'000'000'000'000ll); 103 | 104 | vector v(sz); 105 | 106 | for (ll& x : v) 107 | x = rng(rd); 108 | 109 | return v; 110 | }; 111 | 112 | auto init_prime_vector = [](test_func pr, int sz) -> vector 113 | { 114 | seeder s; 115 | mt19937_64 rd{s}; 116 | uniform_int_distribution rng(2, 3'000'000'000'000'000'000ll); 117 | 118 | vector v(sz); 119 | 120 | for (ll& x : v) { 121 | x = rng(rd); 122 | while (!pr(x)) x++; 123 | } 124 | 125 | return v; 126 | }; 127 | 128 | test("random", is_prime, init_random_vector, num_iters); 129 | test("random_primes", is_prime, init_prime_vector, num_iters); 130 | } -------------------------------------------------------------------------------- /math/segmented_sieve.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma GCC optimize("O3","unroll-loops") 4 | 5 | using namespace std; 6 | 7 | uint32_t const sieve_size = 1<<17; 8 | 9 | vector solve(uint64_t l, uint64_t r) { 10 | uint64_t i = 3, s = 3, n = std::max(l|1, 3ul); 11 | uint64_t sqt = std::sqrt(r); 12 | 13 | vector sieve(sieve_size), is_prime(sqt+1, true); 14 | vector primes, mult; 15 | 16 | vector result; 17 | 18 | if (l <= 2 and r > 2) result.push_back(2); 19 | 20 | for (; i*i < l; i += 2) 21 | if (is_prime[i]) 22 | for (uint64_t j = i*i; j < sqt; j += 2*i) 23 | is_prime[j] = false; 24 | 25 | for (; s*s < l; s += 2) { 26 | if (is_prime[s]) { 27 | primes.push_back(s); 28 | uint64_t nxt = ((l-1)/s+1)*s; 29 | if (nxt == s) nxt += s; 30 | if (nxt%2 == 0) nxt += s; 31 | mult.push_back(nxt-l); 32 | } 33 | } 34 | 35 | for (uint64_t low = l; low < r; low += sieve_size) { 36 | fill(sieve.begin(), sieve.end(), true); 37 | uint64_t high = min(r, low+sieve_size); 38 | 39 | for (; i*i < high; i += 2) 40 | if (is_prime[i]) 41 | for (uint64_t j = i*i; j < sqt; j += 2*i) 42 | is_prime[j] = false; 43 | 44 | for (; s*s < high; s += 2) { 45 | if (is_prime[s]) { 46 | primes.push_back(s); 47 | mult.push_back(s*s - low); 48 | } 49 | } 50 | 51 | for (size_t j = 0; j < primes.size(); j++) { 52 | uint64_t k = mult[j]; 53 | for (uint64_t prime = primes[j]*2; k < sieve_size; k += prime) 54 | sieve[k/2] = false; 55 | mult[j] = k-sieve_size; 56 | } 57 | 58 | for (; n < high; n += 2) 59 | if (sieve[(n-low)/2]) 60 | result.push_back(n); 61 | } 62 | 63 | return result; 64 | } 65 | 66 | int main() { 67 | uint64_t l, r; 68 | cin >> l >> r; 69 | 70 | auto ans = solve(l, r+1); 71 | 72 | for (auto p : ans) cout << p << "\n"; 73 | } 74 | -------------------------------------------------------------------------------- /math/segmented_sieve_bit.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma GCC optimize("O3","unroll-loops") 4 | 5 | using namespace std; 6 | 7 | uint32_t const sieve_size = 1<<20; 8 | 9 | vector solve(uint64_t l, uint64_t r) { 10 | static const int64_t unset_bit[16] = { 11 | ~(1 << 0), ~(1 << 0), 12 | ~(1 << 1), ~(1 << 1), 13 | ~(1 << 2), ~(1 << 2), 14 | ~(1 << 3), ~(1 << 3), 15 | ~(1 << 4), ~(1 << 4), 16 | ~(1 << 5), ~(1 << 5), 17 | ~(1 << 6), ~(1 << 6), 18 | ~(1 << 7), ~(1 << 7) 19 | }; 20 | 21 | uint64_t i = 3, s = 3, n = std::max(l|1, 3ul); 22 | uint64_t sqt = std::sqrt(r); 23 | 24 | vector sieve(sieve_size), is_prime(sqt+1, true); 25 | vector primes, mult; 26 | 27 | vector result; 28 | 29 | if (l <= 2 and r > 2) result.push_back(2); 30 | 31 | for (; i*i < l; i += 2) 32 | if (is_prime[i]) 33 | for (uint64_t j = i*i; j < sqt; j += 2*i) 34 | is_prime[j] = false; 35 | 36 | for (; s*s < l; s += 2) { 37 | if (is_prime[s]) { 38 | primes.push_back(s); 39 | uint64_t nxt = ((l-1)/s+1)*s; 40 | if (nxt == s) nxt += s; 41 | if (nxt%2 == 0) nxt += s; 42 | mult.push_back(nxt-l); 43 | } 44 | } 45 | 46 | for (uint64_t low = l; low < r; low += sieve_size) { 47 | fill(sieve.begin(), sieve.end(), 0xff); 48 | uint64_t high = min(r, low+sieve_size); 49 | 50 | for (; i*i < high; i += 2) 51 | if (is_prime[i]) 52 | for (uint64_t j = i*i; j < sqt; j += 2*i) 53 | is_prime[j] = false; 54 | 55 | for (; s*s < high; s += 2) { 56 | if (is_prime[s]) { 57 | primes.push_back(s); 58 | mult.push_back(s*s - low); 59 | } 60 | } 61 | 62 | for (size_t j = 0; j < primes.size(); j++) { 63 | uint64_t k = mult[j]; 64 | for (uint64_t prime = primes[j]*2; k < sieve_size; k += prime) 65 | sieve[k>>4] &= unset_bit[k&15]; 66 | mult[j] = k-sieve_size; 67 | } 68 | 69 | for (; n < high; n += 2) 70 | if (sieve[(n-low)>>4]&~unset_bit[(n-low)&15]) 71 | result.push_back(n); 72 | } 73 | 74 | return result; 75 | } 76 | 77 | int main() { 78 | uint64_t l, r; 79 | cin >> l >> r; 80 | 81 | auto ans = solve(l, r+1); 82 | 83 | for (auto p : ans) cout << p << "\n"; 84 | } 85 | -------------------------------------------------------------------------------- /math/sieve.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int maxn = 101010101; 6 | 7 | char s[maxn]; 8 | // bitset s; 9 | 10 | vector sieve(int n) 11 | { 12 | for (int i = 2; i*i <= n; i++) 13 | if (!s[i]) 14 | for (int j = i*i; j <= n; j += i) 15 | s[j] = 1; 16 | 17 | vector primes; 18 | for (int i = 2; i <= n; i++) 19 | if (!s[i]) primes.push_back(i); 20 | 21 | return primes; 22 | } 23 | 24 | int main() 25 | { 26 | int n; 27 | cin >> n; 28 | 29 | auto ans = sieve(n); 30 | 31 | cout << ans.size() << "\n"; 32 | } -------------------------------------------------------------------------------- /math/wheel_factorization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma GCC optimize("O3") 4 | 5 | using namespace std; 6 | 7 | using ll = uint64_t; 8 | 9 | template 10 | int tam(T(&)[sz]) { 11 | return sz; 12 | } 13 | 14 | vector factor(ll x) { 15 | static const int primes[] = {2, 3, 5}; 16 | static const int inc[] = { 4, 2, 4, 2, 4, 6, 2, 6 }; 17 | // see compute_wheel.cpp to compute the wheel efficiently 18 | 19 | vector factors; 20 | 21 | for (auto p : primes) 22 | while (x%p == 0) x /= p, factors.push_back(p); 23 | 24 | ll k = 7, i = 0; 25 | 26 | while (k*k <= x) { 27 | while (x%k == 0) 28 | x /= k, factors.push_back(k); 29 | k += inc[i++]; 30 | if (i == tam(inc)) i = 0; 31 | } 32 | 33 | factors.push_back(x); 34 | sort(factors.begin(), factors.end()); 35 | return factors; 36 | } 37 | 38 | int main() { 39 | ll x; 40 | cin >> x; 41 | 42 | auto ans = factor(x); 43 | 44 | for (auto p : ans) cout << p << " "; 45 | cout << "\n"; 46 | } -------------------------------------------------------------------------------- /string/aho_corasick.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define all(x) begin(x), end(x) 4 | 5 | using namespace std; 6 | 7 | int const K = 26; 8 | 9 | struct Vertex { 10 | int next[K]; 11 | int leaf = 0; 12 | int p = -1; 13 | char pch; 14 | int link = -1; 15 | int exit_link = -1; 16 | int go[K]; 17 | int len = 0; 18 | 19 | Vertex(int p=-1, char ch='$') : p(p), pch(ch) { 20 | fill(all(next), -1); 21 | fill(all(go), -1); 22 | } 23 | }; 24 | 25 | vector t(1); 26 | 27 | void add_string(string const& s) { 28 | int v = 0; 29 | for (char ch : s) { 30 | int c = ch - 'a'; 31 | if (t[v].next[c] == -1) { 32 | t[v].next[c] = t.size(); 33 | t.emplace_back(v, ch); 34 | } 35 | v = t[v].next[c]; 36 | } 37 | t[v].leaf++; 38 | t[v].len = s.size(); 39 | } 40 | 41 | int go(int v, char ch); 42 | 43 | int get_link(int v) { 44 | if (t[v].link == -1) { 45 | if (v == 0 || t[v].p == 0) 46 | t[v].link = 0; 47 | else 48 | t[v].link = go(get_link(t[v].p), t[v].pch); 49 | } 50 | return t[v].link; 51 | } 52 | 53 | int get_exit_link(int v) { 54 | if (t[v].exit_link == -1) { 55 | if (v == 0 or t[v].p == 0) { 56 | t[v].exit_link = 0; 57 | } 58 | else { 59 | int nxt = get_link(v); 60 | 61 | if (nxt == 0) { 62 | t[v].exit_link = 0; 63 | } 64 | else if (t[nxt].leaf) { 65 | t[v].exit_link = nxt; 66 | } 67 | else t[v].exit_link = get_exit_link(nxt); 68 | } 69 | } 70 | return t[v].exit_link; 71 | } 72 | 73 | int go(int v, char ch) { 74 | int c = ch - 'a'; 75 | if (t[v].go[c] == -1) { 76 | if (t[v].next[c] != -1) 77 | t[v].go[c] = t[v].next[c]; 78 | else 79 | t[v].go[c] = v == 0 ? 0 : go(get_link(v), ch); 80 | } 81 | return t[v].go[c]; 82 | } 83 | -------------------------------------------------------------------------------- /string/hash.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | using ll = long long; 6 | 7 | class SHash { 8 | private: 9 | static constexpr int nbases = 2; 10 | static constexpr ll bases[nbases] = {91, 107}; 11 | static constexpr ll mods[nbases] = {1000000007, 1000000009}; 12 | 13 | ll v[nbases]; 14 | 15 | public: 16 | SHash() {}; 17 | SHash(string const& s) 18 | { 19 | fill(v, v+nbases, 0); 20 | for (int i = 0; i < nbases; ++i) { 21 | for (char a : s) { 22 | v[i] = (v[i]*bases[i] + a)%mods[i]; 23 | } 24 | } 25 | } 26 | 27 | bool operator==(SHash const& rhs) { 28 | for (int i = 0; i < nbases; i++) 29 | if (v[i] != rhs.v[i]) return false; 30 | return true; 31 | } 32 | 33 | bool operator!=(SHash const& rhs) { 34 | for (int i = 0; i < nbases; i++) 35 | if (v[i] == rhs.v[i]) return false; 36 | return true; 37 | } 38 | }; 39 | 40 | int main() 41 | { 42 | SHash x("fred"), y("fred"); 43 | 44 | cout << (x==y) << "\n"; 45 | } -------------------------------------------------------------------------------- /string/manacher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | template 8 | std::pair, std::vector> manacher(Container const& s) { 9 | int n = s.size(); 10 | std::vector d1(n), d2(n); 11 | 12 | for (int i = 0, l = 0, r = -1; i < n; i++) { 13 | int k = (i > r) ? 1 : std::min(d1[l+r-i], r-i+1); 14 | while (k <= i and i+k < n and s[i-k] == s[i+k]) { 15 | k++; 16 | } 17 | d1[i] = k--; 18 | if (i + k > r) { 19 | l = i - k; 20 | r = i + k; 21 | } 22 | } 23 | 24 | for (int i = 0, l = 0, r = -1; i < n; i++) { 25 | int k = (i > r) ? 0 : std::min(d2[l+r-i+1], r-i+1); 26 | while (k+1 <= i and i+k < n and s[i-k-1] == s[i+k]) { 27 | k++; 28 | } 29 | d2[i] = k--; 30 | if (i + k > r) { 31 | l = i - k - 1; 32 | r = i + k; 33 | } 34 | } 35 | 36 | // d1 odd lenght palindromes center (i) 37 | // d2 even lenght palindromes center (i-1, i) 38 | return {d1, d2}; 39 | } 40 | 41 | int main() { 42 | std::string s; 43 | std::cin >> s; 44 | 45 | auto [d1, d2] = manacher(s); 46 | 47 | for (auto i : d1) std::cout << i << " "; 48 | std::cout << "\n"; 49 | 50 | for (auto i : d2) std::cout << i << " "; 51 | std::cout << "\n"; 52 | } -------------------------------------------------------------------------------- /string/prefix.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | vector prefix(string const& s) { 6 | int const n = s.size(); 7 | vector pi(n); 8 | for (int i = 1; i < n; i++) { 9 | int j = pi[i-1]; 10 | while (j and s[i] != s[j]) j = pi[j-1]; 11 | if (s[i] == s[j]) j++; 12 | pi[i] = j; 13 | } 14 | return pi; 15 | } 16 | 17 | vector> prefix_automata(string s) { 18 | s += '#'; 19 | int const n = s.size(); 20 | auto aut = vector>(n, vector(26)); 21 | auto pi = prefix(s); 22 | 23 | for (int i = 0; i < n; i++) { 24 | for (int c = 0; c < 26; c++) { 25 | if (i > 0 && 'a' + c != s[i]) 26 | aut[i][c] = aut[pi[i-1]][c]; 27 | else 28 | aut[i][c] = i + ('a' + c == s[i]); 29 | } 30 | } 31 | return aut; 32 | } 33 | 34 | int main() {} -------------------------------------------------------------------------------- /string/suffix_array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | vector sort_cyclic_shifts(string const& s) { 6 | int const n = s.size(); 7 | int const alphabet = 256; 8 | vector p(n), c(n), cnt(max(alphabet, n), 0); 9 | 10 | for (int i = 0; i < n; i++) 11 | cnt[s[i]]++; 12 | for (int i = 1; i < alphabet; i++) 13 | cnt[i] += cnt[i-1]; 14 | for (int i = 0; i < n; i++) 15 | p[--cnt[s[i]]] = i; 16 | 17 | c[p[0]] = 0; 18 | int classes = 1; 19 | 20 | for (int i = 1; i < n; i++) { 21 | if (s[p[i]] != s[p[i-1]]) 22 | classes++; 23 | c[p[i]] = classes - 1; 24 | } 25 | 26 | vector pn(n), cn(n); 27 | 28 | for (int h = 0; (1 << h) < n; ++h) { 29 | for (int i = 0; i < n; i++) { 30 | pn[i] = p[i] - (1 << h); 31 | if (pn[i] < 0) 32 | pn[i] += n; 33 | } 34 | 35 | fill(cnt.begin(), cnt.begin() + classes, 0); 36 | for (int i = 0; i < n; i++) 37 | cnt[c[pn[i]]]++; 38 | for (int i = 1; i < classes; i++) 39 | cnt[i] += cnt[i-1]; 40 | for (int i = n-1; i >= 0; i--) 41 | p[--cnt[c[pn[i]]]] = pn[i]; 42 | cn[p[0]] = 0; 43 | classes = 1; 44 | 45 | for (int i = 1; i < n; i++) { 46 | pair cur = {c[p[i]], c[(p[i] + (1 << h)) % n]}; 47 | pair prev = {c[p[i-1]], c[(p[i-1] + (1 << h)) % n]}; 48 | if (cur != prev) 49 | ++classes; 50 | cn[p[i]] = classes - 1; 51 | } 52 | c.swap(cn); 53 | } 54 | return p; 55 | } 56 | 57 | vector suffix_array(string s) { 58 | s += "$"; 59 | vector sorted_shifts = sort_cyclic_shifts(s); 60 | sorted_shifts.erase(sorted_shifts.begin()); 61 | return sorted_shifts; 62 | } --------------------------------------------------------------------------------