├── .DS_Store ├── .github └── workflows │ └── verify.yml ├── .gitignore ├── .verify-helper ├── config.toml ├── docs │ └── _config.yml └── timestamps.remote.json ├── DP ├── .gitignore ├── cnt_distinct_subseq.h ├── coin_exchange.h ├── count_inversions.h ├── edit_distance.h ├── knapsack.h ├── lis.h ├── optimizations │ ├── convex_hull.h │ ├── convex_hull_2.h │ ├── divide_conquer.cpp │ ├── dynamic_hull.h │ └── knuth.cpp ├── reroot_tree_dp.cpp └── tests │ ├── aizu_alds1_5_d_count_inversions.test.cpp │ ├── aizu_dpl_1_d_lis.test.cpp │ ├── dynamic_hull_lineaddgetmin.test.cpp │ ├── yosupo_cnt_distinct_subseq.test.cpp │ └── yosupo_lis.test.cpp ├── DataStructure ├── BinaryTrie.h ├── DSU │ ├── DSU_dynamic_connectivity.h │ ├── DSU_partially_persistent.h │ ├── DSU_partially_persistent_with_color.h │ ├── DSU_persistent.h │ ├── DSU_rollback.h │ ├── DSU_weighted.h │ └── DisjointSet.h ├── Fenwick │ ├── Fenwick.h │ ├── Fenwick2D.h │ ├── Fenwick2D_smallN.h │ └── PartiallyPersistentFenwick.h ├── HeavyLight.cpp ├── HeavyLight_adamant.h ├── KDTree.h ├── LCA.h ├── LCA_RMQ.h ├── LazySegTree.h ├── LiChaoSegTree.h ├── LinkCutTree.h ├── Mo │ ├── MoAlgorithm.h │ ├── MoAlgorithmWithUndo.h │ ├── MoAlgorithmWithUpdates.h │ ├── TreeMoAlgorithm.h │ └── TreeMoAlgorithmWithUpdates.h ├── OrderedSet.h ├── PersistentArray.h ├── PersistentSegTree.h ├── RMQ.h ├── RangeSet.h ├── STL │ ├── order_statistic.cpp │ ├── pbds_faster_map.h │ ├── rope.cpp │ └── unordered_map_pair.h ├── SegTree.h ├── SegTree2D.h ├── SegmentTreeBeats.cpp ├── WaveletMatrix.h ├── misc │ ├── area_of_union_of_rectangles.h │ ├── ndvec.h │ └── offset_vector.h ├── splay_tree.h └── test │ ├── .gitignore │ ├── aizu_dsl_1_a_dsu.test.cpp │ ├── aizu_dsl_1_b_dsu_weighted.test.cpp │ ├── aizu_dsl_2_a_segment_tree_rmq_update.test.cpp │ ├── aizu_dsl_2_b_fenwick_aizu.test.cpp │ ├── aizu_dsl_2_b_segment_tree_sum.test.cpp │ ├── aizu_dsl_2_d_rangeset.test.cpp │ ├── aizu_dsl_2_d_segment_tree_rangeset.test.cpp │ ├── aizu_dsl_2_e_segment_tree_rangeadd.test.cpp │ ├── aizu_dsl_2_f_segment_tree_rangesetmin.test.cpp │ ├── aizu_dsl_2_g_segment_tree_rangeaddsum.test.cpp │ ├── aizu_dsl_2_h_segment_tree_rangeaddmin.test.cpp │ ├── aizu_dsl_2_i_segment_tree_rangesetsum.test.cpp │ ├── aizu_dsl_4_a_range_set.test.cpp │ ├── aizu_grl_5_c_hld_lca.test.cpp │ ├── aizu_grl_5_c_lca.test.cpp │ ├── aizu_grl_5_d_hld_edge.test.cpp │ ├── aizu_grl_5_e_hld_edge.test.cpp │ ├── area_of_union_of_rectangles.test.cpp │ ├── binary_trie.test.cpp │ ├── dsu.test.cpp │ ├── fenwick.test.cpp │ ├── fenwick_2d_pointaddrectsum.test.cpp │ ├── fenwick_2d_rectsum.test.cpp │ ├── fenwick_pointaddrangesum.test.cpp │ ├── hld_lca.test.cpp │ ├── hld_vertexaddpathsum.test.cpp │ ├── hld_vertexaddsubtreesum.test.cpp │ ├── hld_vertexsetpathcomposite.test.cpp │ ├── lca.test.cpp │ ├── li_chao_seg_tree_lineaddgetmin.test.cpp │ ├── li_chao_seg_tree_segaddgetmin.test.cpp │ ├── link_cut_tree_addpathsum.test.cpp │ ├── link_cut_tree_vertexaddsubtreesum.test.cpp │ ├── link_cut_tree_vertexsetpathcomposite.test.cpp │ ├── mo_algorithm.test.cpp │ ├── mo_algorithm_with_undo.test.cpp │ ├── persistent_dsu.test.cpp │ ├── persistent_fenwick_tree_rmq.test.cpp │ ├── rmq.test.cpp │ ├── segment_tree_2d_pointaddrectsum.test.cpp │ ├── segment_tree_pointaddrangesum.test.cpp │ ├── segment_tree_pointsetrangecomposite.test.cpp │ ├── segment_tree_rangeaffinepointget.test.cpp │ ├── segment_tree_rangeaffinerangesum.test.cpp │ ├── segment_tree_staticrmq.test.cpp │ ├── splay_tree.test.cpp │ ├── wavelet_matrix_rangekthsmallest.test.cpp │ ├── wavelet_matrix_staticrangefreq.test.cpp │ ├── yosupo_hld_kth_vertex_on_path.test.cpp │ ├── yosupo_rangereversesum_splay.test.cpp │ └── yukicoder_674_range_set.test.cpp ├── Geometry ├── .gitignore ├── 3d.h ├── RectInRect.h ├── basic.h ├── circle.h ├── closest_pair.h ├── n_segment_intersects.h ├── polygon.h ├── polygon_region.h ├── segment_union.h ├── simple_polygon_check.h ├── smallestEnclosingCircle.h ├── soddy_circles.txt ├── spherical.h ├── tests │ ├── aizu_cgl_1_a_basic_projection.test.cpp │ ├── aizu_cgl_1_b_basic_reflection.test.cpp │ ├── aizu_cgl_1_c_basic_ccw.test.cpp │ ├── aizu_cgl_2_a_basic_line.test.cpp │ ├── aizu_cgl_2_b_basic_segment_intersect.test.cpp │ ├── aizu_cgl_2_c_basic_line_intersection.test.cpp │ ├── aizu_cgl_2_d_basic_segment_distance.test.cpp │ ├── aizu_cgl_3_a_polygon_area.test.cpp │ ├── aizu_cgl_3_b_polygon_is_convex.test.cpp │ ├── aizu_cgl_3_c_polygon_in_polygon.test.cpp │ ├── aizu_cgl_4_a_polygon_convex_hull.test.cpp │ ├── aizu_cgl_4_b_polygon_convex_diameter.test.cpp │ ├── aizu_cgl_4_c_polygon_convex_cut.test.cpp │ ├── aizu_cgl_5_a_closest_pair.test.cpp │ ├── aizu_cgl_7_a_cicle_tangents.test.cpp │ ├── aizu_cgl_7_d_circle_line_intersection.test.cpp │ ├── aizu_cgl_7_e_circle_circle_intersection.test.cpp │ ├── aizu_cgl_7_f_circle_tangent_points.test.cpp │ ├── aizu_cgl_7_g_circle_circle_tangent_points.test.cpp │ ├── aizu_cgl_7_i_circle_common_area.test.cpp │ ├── polygon_in_convex.test.cpp │ ├── z_basic_ccw.test.cpp │ ├── z_basic_segment_intersect.test.cpp │ ├── z_polygon_area.test.cpp │ ├── z_polygon_convexhull.test.cpp │ └── z_polygon_is_convex.test.cpp └── voronoi.cpp ├── Graph ├── 2sat.h ├── DfsTree │ ├── .gitignore │ ├── BiconnectedComponent.h │ ├── BridgeArticulation.h │ └── StronglyConnected.h ├── DirectedMST.h ├── Matching │ ├── .gitignore │ ├── BipartiteMatching.h │ ├── GeneralMatching.h │ ├── HungarianLMH.h │ ├── Hungarian_short.h │ └── StableMarriage.h ├── MaxClique.h ├── MaxFlow │ ├── .gitignore │ ├── GomoryHu.h │ ├── MaxClosure.txt │ ├── MaxFlowDinic.h │ ├── MaxFlowDinicTrace.h │ ├── MaxFlowHLPP.h │ ├── MaxFlowLMH.h │ ├── MaxFlowPR.h │ ├── MinCostMaxFlowPR.h │ ├── MinCostMaxFlowSPFA.h │ ├── MinimumCut.h │ └── upper_lower.txt ├── Misc │ ├── EulerPath.h │ └── EulerPathDirected.h ├── bfs.h ├── bfs_using_map.h ├── bipartite_coloring.h ├── bipartite_edge_coloring.h ├── dijkstra.h ├── find_triangles.h ├── floyd.h ├── ford_bellman.h ├── mst.h ├── tests │ ├── aizu_alds1_11_c_bfs.test.cpp │ ├── aizu_grl_1_a_dijkstra_aizu.test.cpp │ ├── aizu_grl_1_c_floyd.test.cpp │ ├── aizu_grl_2_a_mst.test.cpp │ ├── aizu_grl_2_b_directed_mst.test.cpp │ ├── aizu_grl_3_a_articulation_points.test.cpp │ ├── aizu_grl_3_b_bridge.test.cpp │ ├── aizu_grl_3_c_strongly_connected.test.cpp │ ├── aizu_grl_4_a_strongly_connected_cycle_check.test.cpp │ ├── aizu_grl_5_a_tree_diameter.test.cpp │ ├── aizu_grl_6_a_maxflow_dinic.test.cpp │ ├── aizu_grl_6_a_maxflow_hlpp.test.cpp │ ├── aizu_grl_6_a_maxflow_pr.test.cpp │ ├── aizu_grl_6_b_mincost_maxflow.test.cpp │ ├── aizu_grl_6_b_mincost_maxflow_spfa.test.cpp │ ├── aizu_grl_7_a_matching_bipartite.test.cpp │ ├── bipartite_coloring.test.cpp │ ├── bridge_biconnected.test.cpp │ ├── clique_maxindependentset.test.cpp │ ├── dijkstra.test.cpp │ ├── directed_mst.test.cpp │ ├── matching_bipartite.test.cpp │ ├── matching_bipartite_weighted.test.cpp │ ├── matching_bipartite_weighted_2.test.cpp │ ├── matching_general.test.cpp │ ├── strongly_connected.test.cpp │ ├── tree_diameter.test.cpp │ ├── triangles.test.cpp │ ├── two_sat.test.cpp │ └── yosupo_mst.test.cpp ├── topo_sort.h └── tree_diameter.h ├── Java ├── BigMath.java ├── InputReader.java ├── JS.java ├── Rational.java └── RegexTest.java ├── ML └── lightbgm_example.py ├── Math ├── Fraction.h ├── Linear │ ├── Gaussian.h │ ├── GaussianBinary.h │ └── duality.png ├── LinearRecurrence_BerlekampMassey.h ├── Matrix.h ├── NumberTheory │ ├── CRT_chemthan.h │ ├── ChineseRemainder.h │ ├── ExtendedEuclid.h │ ├── FactorialMod.h │ ├── Pollard_factorize.h │ ├── PrimitiveRoot.h │ ├── SqrtMod.h │ ├── cnt_divisors.h │ ├── congruence.h │ ├── factorize_brent.h │ └── x_k_a.h ├── Polynomial │ ├── FFT.h │ ├── FormalPowerSeries.h │ ├── Karatsuba.h │ ├── NTT.h │ ├── NTT_chemthan.h │ ├── PolynomialValues.h │ └── xorFFT.h ├── Prime │ ├── EulerPhi.h │ ├── PrimePi.h │ ├── RabinMiller.h │ ├── RabinMiller32.h │ ├── SegmentedSieve.h │ ├── Sieve.h │ └── SieveFast.h ├── Pure │ ├── Cubic.h │ ├── PythagoreTriple.h │ ├── farey.h │ ├── fibo.h │ ├── lagrange.h │ ├── moebius.txt │ ├── n_gonal.txt │ └── pell_equation.h ├── Simplex.h ├── SumDiv_SumMod.h ├── bigint.h ├── modint.h ├── modulo.h ├── multiplicative_function.h ├── multiplicative_functions_linear.h ├── nim_product.h └── tests │ ├── .gitignore │ ├── aizu_ntl_1_a_factorize.test.cpp │ ├── aizu_ntl_1_b_modulo_pow.test.cpp │ ├── aizu_ntl_1_d_euler_phi.test.cpp │ ├── aizu_ntl_1_e_extended_euclid.test.cpp │ ├── aizu_ntl_2_a_bigint_add.test.cpp │ ├── aizu_ntl_2_b_bigint_sub.test.cpp │ ├── aizu_ntl_2_c_bigint_mul.test.cpp │ ├── aizu_ntl_2_c_bigint_mul_karatsuba.test.cpp │ ├── aizu_ntl_2_d_bigint_div.test.cpp │ ├── aizu_ntl_2_e_bigint_mod.test.cpp │ ├── aizu_ntl_2_f_bigint_mul_fft.test.cpp │ ├── berlekamp_massey.test.cpp │ ├── cnt_divisors_stress.test.cpp │ ├── convolution_and.test.cpp │ ├── convolution_xor.test.cpp │ ├── euler_phi_stress.test.cpp │ ├── factorize.test.cpp │ ├── formal_power_series_multiply.test.cpp │ ├── formal_power_series_multiply_any_mod.test.cpp │ ├── is_prime_yukicoder.test.cpp │ ├── matrix_det.test.cpp │ ├── matrix_inverse.test.cpp │ ├── matrix_mult.test.cpp │ ├── nimber.test.cpp │ ├── ntt.test.cpp │ ├── ntt_any_mod.test.cpp │ ├── ntt_chemthan.test.cpp │ ├── ntt_chemthan_any_mod.test.cpp │ ├── ntt_chemthan_any_mod_2.test.cpp │ ├── prime_pi.test.cpp │ ├── rabin_miller_32_stress.test.cpp │ ├── sieve.test.cpp │ ├── sieve_fast.test.cpp │ ├── smallest_prime_factor_stress.test.cpp │ ├── sqrt_mod.test.cpp │ ├── sumdiv.test.cpp │ ├── yosupo_bigint_add.test.cpp │ └── yosupo_primality_rabin_miller.test.cpp ├── Misc ├── Die.cpp ├── Die.h ├── Johnson.txt ├── KnightMove.h ├── Rubik.h ├── bitmask_utils.h ├── board_utils.h ├── compress.h ├── container_pipe_utils.h ├── input_utils.h ├── int128.h ├── left_nearest_smaller.h ├── local_search.cpp ├── magic.cpp ├── mink.h ├── number_utils.h ├── radix_sort_32bit.h ├── tests │ ├── aizu_dpl_3_b_largest_01_rectangle.test.cpp │ ├── aizu_dpl_3_c_largest_histogram.test.cpp │ ├── pipe_utils.test.cpp │ └── yosupo_int128.test.cpp ├── two_pointers.h └── vec_utils.h ├── README.md ├── String ├── .gitignore ├── AhoCorasick.h ├── PalindromeTree_eertree.cpp ├── SuffixArray.h ├── hash.h ├── kmp.h ├── lyndon.cpp ├── lyndon.h ├── maine_lorentz.h ├── manacher.h ├── minmove.cpp ├── minmove.h ├── suffix_automaton.h ├── tests │ ├── aizu_alds_14_b_string_hash.test.cpp │ ├── lcp.test.cpp │ ├── manacher.test.cpp │ ├── suffix_array.test.cpp │ ├── suffix_array_queries.test.cpp │ ├── yukicoder_1408_string_hash_lcp.test.cpp │ ├── zfunc.test.cpp │ └── zfunc_hash.test.cpp ├── trie.h └── zfunc.h ├── atcoder ├── internal_math.hpp ├── internal_type_traits.hpp └── modint.hpp ├── buffered_reader.h ├── debug.h ├── stack_increase.cpp ├── template.h └── vimrc /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngthanhtrung23/ACM_Notebook_new/b54b203064b3f3a9391fbee3267c628e51f5ca3e/.DS_Store -------------------------------------------------------------------------------- /.github/workflows/verify.yml: -------------------------------------------------------------------------------- 1 | name: verify 2 | 3 | on: push 4 | 5 | jobs: 6 | verify: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v1 11 | 12 | - name: Set up Python 13 | uses: actions/setup-python@v1 14 | 15 | - name: Install dependencies 16 | run: pip3 install -U git+https://github.com/ngthanhtrung23/verification-helper.git@master 17 | 18 | - name: Run tests 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | YUKICODER_TOKEN: ${{ secrets.YUKICODER_TOKEN }} 22 | GH_PAT: ${{ secrets.GH_PAT }} 23 | run: oj-verify all --jobs 2 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .fuse* 2 | *.exe 3 | *.dSYM/ 4 | *.swp 5 | *.class 6 | input.txt 7 | output.txt 8 | 9 | # Compiled code 10 | template 11 | 12 | # Gen test 13 | gentest* 14 | *.test 15 | in 16 | 17 | # IDE 18 | *.sublime-project 19 | *.sublime-workspace 20 | -------------------------------------------------------------------------------- /.verify-helper/config.toml: -------------------------------------------------------------------------------- 1 | [[languages.cpp.environments]] 2 | CXX = "g++" 3 | CXXFLAGS = ["-std=c++17", "-O2"] 4 | -------------------------------------------------------------------------------- /.verify-helper/docs/_config.yml: -------------------------------------------------------------------------------- 1 | exclude: ["atcoder", "Java"] 2 | -------------------------------------------------------------------------------- /DP/.gitignore: -------------------------------------------------------------------------------- 1 | ZOJ_2860 2 | knuth 3 | divide_conquer 4 | -------------------------------------------------------------------------------- /DP/cnt_distinct_subseq.h: -------------------------------------------------------------------------------- 1 | #include "../Misc/compress.h" 2 | 3 | // Returns number of distinct, non-empty subsequences {{{ 4 | // T = type of input elements 5 | // OutT = type of output (e.g. ModInt) 6 | template 7 | OutT cnt_distinct_subsequences(std::vector a) { 8 | auto compressor = CompressorBuilder{a}.build(); 9 | compressor.compress_inplace(a); 10 | 11 | std::vector f(a.size() + 1); 12 | std::vector last(a.size() + 1, -1); 13 | f[0] = 1; 14 | for (size_t i = 0; i < a.size(); ++i) { 15 | f[i+1] = f[i] * 2; 16 | if (last[a[i]] >= 0) f[i+1] -= f[last[a[i]]]; 17 | last[a[i]] = i; 18 | } 19 | return f.back() - 1; 20 | } 21 | // }}} 22 | -------------------------------------------------------------------------------- /DP/coin_exchange.h: -------------------------------------------------------------------------------- 1 | // Returns number of ways we can exchange k using set of coins {{{ 2 | template 3 | T coin_exchange(int k, std::vector coins) { 4 | std::vector f(k + 1); 5 | f[0] = 1; 6 | for (int coin : coins) { 7 | for (int i = coin; i <= k; ++i) { 8 | f[i] += f[i-coin]; 9 | } 10 | } 11 | return f.back(); 12 | } 13 | // }}} 14 | -------------------------------------------------------------------------------- /DP/count_inversions.h: -------------------------------------------------------------------------------- 1 | #include "../Misc/compress.h" 2 | #include "../DataStructure/Fenwick/Fenwick.h" 3 | 4 | // Given vector vs, return number of inversions 5 | template 6 | long long count_inversions(vector vs) { 7 | int n = vs.size(); 8 | auto compressor = CompressorBuilder{vs}.build(); 9 | compressor.compress_inplace(vs); 10 | Fenwick bit(n); 11 | 12 | long long res = 0; 13 | for (auto v : vs) { 14 | res += bit.get(v+1, n); 15 | bit.update(v, +1); 16 | } 17 | return res; 18 | } 19 | -------------------------------------------------------------------------------- /DP/edit_distance.h: -------------------------------------------------------------------------------- 1 | // Minimum number of operations to transform string a => string b 2 | // In one operation, we can either modify 1 character, delete 1 character or 3 | // insert 1 character (insert is not needed in this case) 4 | // 5 | // Edit distance {{{ 6 | int edit_distance(std::string a, std::string b) { 7 | int la = a.size(); 8 | int lb = b.size(); 9 | a = " " + a + " "; 10 | b = " " + b + " "; 11 | 12 | std::vector> f(la + 1, std::vector (lb + 1, la + lb)); 13 | 14 | // corner cases 15 | for (int j = 0; j <= lb; ++j) f[0][j] = j; 16 | for (int i = 0; i <= la; ++i) f[i][0] = i; 17 | 18 | // DP 19 | for (int i = 1; i <= la; ++i) { 20 | for (int j = 1; j <= lb; ++j) { 21 | if (a[i] == b[j]) f[i][j] = f[i-1][j-1]; 22 | else f[i][j] = 1 + std::min({ 23 | f[i-1][j-1], // modify 24 | f[i][j-1], // remove b[j] 25 | f[i-1][j], // remove a[i] 26 | }); 27 | } 28 | } 29 | 30 | return f.back().back(); 31 | } 32 | // }}} 33 | -------------------------------------------------------------------------------- /DP/knapsack.h: -------------------------------------------------------------------------------- 1 | // Knapsack 01 {{{ 2 | // Select subset of items, such that sum(weights) <= capacity 3 | // and sum(values) is maximum 4 | int knapsack01( 5 | int capacity, 6 | const std::vector& weights, 7 | const std::vector& values) { 8 | int n = weights.size(); 9 | std::vector f(capacity + 1, 0); 10 | for (int i = 0; i < n; ++i) { 11 | for (int j = capacity; j >= weights[i]; --j) { 12 | f[j] = max(f[j], f[j-weights[i]] + values[i]); 13 | } 14 | } 15 | 16 | return *max_element(f.begin(), f.end()); 17 | } 18 | // }}} 19 | // Knapsack unbounded {{{ 20 | // Select subset of items, such that sum(weights) <= capacity 21 | // and sum(values) is maximum 22 | // An item can be selected unlimited number of times 23 | int knapsack_unbounded( 24 | int capacity, 25 | const std::vector& weights, 26 | const std::vector& values) { 27 | int n = weights.size(); 28 | std::vector f(capacity + 1, 0); 29 | for (int i = 0; i < n; ++i) { 30 | for (int j = weights[i]; j <= capacity; ++j) { 31 | f[j] = max(f[j], f[j-weights[i]] + values[i]); 32 | } 33 | } 34 | 35 | return *max_element(f.begin(), f.end()); 36 | } 37 | // }}} 38 | -------------------------------------------------------------------------------- /DP/optimizations/convex_hull.h: -------------------------------------------------------------------------------- 1 | // Original Recurrence: 2 | // dp[i] = min( dp[j] + b[j]*a[i] ) for j < i 3 | // Condition: 4 | // b[j] >= b[j+1] 5 | // a[i] <= a[i+1] 6 | // To solve: 7 | // Hull hull; 8 | // FOR(i,1,n) { 9 | // dp[i] = hull.get(a[i]); 10 | // hull.add(b[i], dp[i]); 11 | // } 12 | 13 | const int MAXN = 100100; 14 | 15 | struct Hull { 16 | long long a[MAXN], b[MAXN]; 17 | double x[MAXN]; 18 | int head, tail; 19 | 20 | Hull(): head(1), tail(0) {} 21 | 22 | long long get(long long xQuery) { 23 | if (head > tail) return 0; 24 | while (head < tail && x[head + 1] <= xQuery) head++; 25 | x[head] = xQuery; 26 | return a[head] * xQuery + b[head]; 27 | } 28 | 29 | void add(long long aNew, long long bNew) { 30 | double xNew = -1e18; 31 | while (head <= tail) { 32 | if (aNew == a[tail]) return; 33 | xNew = 1.0 * (b[tail] - bNew) / (aNew - a[tail]); 34 | if (head == tail || xNew >= x[tail]) break; 35 | tail--; 36 | } 37 | a[++tail] = aNew; 38 | b[tail] = bNew; 39 | x[tail] = xNew; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /DP/optimizations/dynamic_hull.h: -------------------------------------------------------------------------------- 1 | // source: https://github.com/niklasb/contest-algos/blob/master/convex_hull/dynamic.cpp 2 | // Tested: 3 | // - https://judge.yosupo.jp/problem/line_add_get_min 4 | using ll = long long; 5 | const ll INF = (1LL<<62); 6 | struct Line { 7 | ll m, b; 8 | mutable function succ; 9 | bool operator<(const Line& rhs) const { 10 | if (rhs.b != -INF) return m < rhs.m; 11 | const Line* s = succ(); 12 | if (!s) return 0; 13 | ll x = rhs.m; 14 | return b - s->b < (s->m - m) * x; 15 | } 16 | }; 17 | 18 | struct HullDynamic : public multiset { // will maintain upper hull for maximum 19 | bool bad(iterator y) { 20 | auto z = next(y); 21 | if (y == begin()) { 22 | if (z == end()) return 0; 23 | return y->m == z->m && y->b <= z->b; 24 | } 25 | auto x = prev(y); 26 | if (z == end()) return y->m == x->m && y->b <= x->b; 27 | return 1.0 * (x->b - y->b)*(z->m - y->m) >= 1.0 * (y->b - z->b)*(y->m - x->m); 28 | } 29 | void insert_line(ll m, ll b) { 30 | auto y = insert({ m, b }); 31 | y->succ = [=] { return next(y) == end() ? 0 : &*next(y); }; 32 | if (bad(y)) { erase(y); return; } 33 | while (next(y) != end() && bad(next(y))) erase(next(y)); 34 | while (y != begin() && bad(prev(y))) erase(prev(y)); 35 | } 36 | ll eval(ll x) { 37 | auto l = *lower_bound((Line) { x, -INF }); 38 | return l.m * x + l.b; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /DP/tests/aizu_alds1_5_d_count_inversions.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_5_D" 2 | 3 | #include "../../template.h" 4 | #include "../count_inversions.h" 5 | 6 | void solve() { 7 | int n; cin >> n; 8 | auto a = read_vector (n); 9 | 10 | cout << count_inversions(a) << endl; 11 | } 12 | -------------------------------------------------------------------------------- /DP/tests/aizu_dpl_1_d_lis.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_1_D" 2 | 3 | #include "../../template.h" 4 | #include "../lis.h" 5 | 6 | void solve() { 7 | int n; cin >> n; 8 | vector a(n); for(int& x : a) cin >> x; 9 | cout << lis_strict(a) << endl; 10 | } 11 | -------------------------------------------------------------------------------- /DP/tests/dynamic_hull_lineaddgetmin.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/line_add_get_min" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../optimizations/dynamic_hull.h" 7 | 8 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 9 | 10 | int32_t main() { 11 | ios::sync_with_stdio(0); cin.tie(0); 12 | int n, q; cin >> n >> q; 13 | HullDynamic hull; 14 | REP(i,n) { 15 | long long a, b; cin >> a >> b; 16 | hull.insert_line(-a, -b); 17 | } 18 | REP(i,q) { 19 | int typ; cin >> typ; 20 | if (typ == 0) { 21 | long long a, b; cin >> a >> b; 22 | hull.insert_line(-a, -b); 23 | } else { 24 | long long x; cin >> x; 25 | cout << -hull.eval(x) << '\n'; 26 | } 27 | } 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /DP/tests/yosupo_cnt_distinct_subseq.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/number_of_subsequences" 2 | 3 | #include "../../template.h" 4 | #include "../cnt_distinct_subseq.h" 5 | #include "../../Math/modint.h" 6 | 7 | const int MOD = 998244353; 8 | using mint = ModInt; 9 | 10 | void solve() { 11 | int n; cin >> n; 12 | vector a(n); 13 | REP(i,n) cin >> a[i]; 14 | 15 | cout << cnt_distinct_subsequences (a) << endl; 16 | } 17 | -------------------------------------------------------------------------------- /DP/tests/yosupo_lis.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/longest_increasing_subsequence" 2 | 3 | #include "../../template.h" 4 | #include "../lis.h" 5 | 6 | void solve() { 7 | int n; cin >> n; 8 | vector a(n); for(int& x : a) cin >> x; 9 | 10 | auto res = lis_strict_trace(a); 11 | std::cout << res.size() << std::endl; 12 | for (int i : res) std::cout << i << ' '; 13 | std::cout << std::endl; 14 | } 15 | -------------------------------------------------------------------------------- /DataStructure/DSU/DSU_partially_persistent.h: -------------------------------------------------------------------------------- 1 | // Partially persistent DSU 2 | // 3 | // Supports: 4 | // - Linear history (version t+1 always build on top of version t) 5 | // - Query history information at version t 6 | // 7 | // Tested: 8 | // - https://oj.vnoi.info/problem/vnoicup22_r2_c 9 | struct PartiallyPersistentDSU { 10 | vector lab, t_unite; 11 | 12 | PartiallyPersistentDSU(int n) 13 | : lab(n + 1, -1), t_unite(n + 1, INT_MAX) {} 14 | 15 | // return root 16 | int getRoot(int t, int x) { 17 | if (t_unite[x] > t) { 18 | return x; 19 | } 20 | return getRoot(t, lab[x]); 21 | } 22 | 23 | void merge(int t, int x, int y) { 24 | int root_x = getRoot(t, x); 25 | int root_y = getRoot(t, y); 26 | x = root_x; y = root_y; 27 | if (x == y) { 28 | return; 29 | } 30 | if (lab[x] > lab[y]) { 31 | std::swap(x, y); 32 | } 33 | lab[x] += lab[y]; 34 | lab[y] = x; 35 | t_unite[y] = t; 36 | } 37 | 38 | bool same_component(int t, int u, int v) { 39 | return getRoot(t, u) == getRoot(t, v); 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /DataStructure/DSU/DSU_weighted.h: -------------------------------------------------------------------------------- 1 | template 2 | struct WeightedDSU { 3 | std::vector lab; 4 | std::vector w; // relative to parent 5 | 6 | WeightedDSU(int n) : lab(n, -1), w(n) {} 7 | 8 | int getRoot(int u) { 9 | if (lab[u] < 0) return u; 10 | return getRoot(lab[u]); 11 | } 12 | 13 | int weight(int u) { 14 | if (lab[u] < 0) return w[u]; 15 | return w[u] + weight(lab[u]); 16 | } 17 | 18 | // weight(t) = weight(s) + diff 19 | // returns false if contradicts 20 | bool merge(int s, int t, S diff) { 21 | // jump to root 22 | diff = diff + weight(s) - weight(t); 23 | s = getRoot(s); 24 | t = getRoot(t); 25 | if (s == t) return diff == 0; 26 | if (lab[s] > lab[t]) { 27 | std::swap(s, t); 28 | diff = -diff; 29 | } 30 | lab[s] += lab[t]; 31 | lab[t] = s; 32 | w[t] = diff; 33 | return true; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /DataStructure/DSU/DisjointSet.h: -------------------------------------------------------------------------------- 1 | // DisjointSet {{{ 2 | struct DSU { 3 | vector lab; 4 | 5 | DSU(int n) : lab(n+1, -1) {} 6 | 7 | int getRoot(int u) { 8 | if (lab[u] < 0) return u; 9 | return lab[u] = getRoot(lab[u]); 10 | } 11 | 12 | bool merge(int u, int v) { 13 | u = getRoot(u); v = getRoot(v); 14 | if (u == v) return false; 15 | if (lab[u] > lab[v]) swap(u, v); 16 | lab[u] += lab[v]; 17 | lab[v] = u; 18 | return true; 19 | } 20 | 21 | bool same_component(int u, int v) { 22 | return getRoot(u) == getRoot(v); 23 | } 24 | 25 | int component_size(int u) { 26 | return -lab[getRoot(u)]; 27 | } 28 | }; 29 | // }}} 30 | -------------------------------------------------------------------------------- /DataStructure/Fenwick/Fenwick.h: -------------------------------------------------------------------------------- 1 | // 1D Fenwick {{{ 2 | // 0 based index 3 | // 4 | // Tested: 5 | // - https://judge.yosupo.jp/problem/static_range_sum 6 | // - https://judge.yosupo.jp/problem/point_add_range_sum 7 | template< 8 | typename T // need to support operators + - 9 | > struct Fenwick { 10 | Fenwick(int _n) : n(_n), f(_n + 1) {} 11 | 12 | // a[u] += val 13 | void update(int u, T val) { 14 | assert(0 <= u && u < n); 15 | ++u; 16 | for (; u <= n; u += u & -u) { 17 | f[u] += val; 18 | } 19 | } 20 | 21 | // return a[0] + .. + a[u-1] 22 | T get(int u) const { 23 | assert(0 <= u && u <= n); 24 | T res = 0; 25 | for (; u > 0; u -= u & -u) { 26 | res += f[u]; 27 | } 28 | return res; 29 | } 30 | 31 | // return a[l] + .. + a[r-1] 32 | T get(int l, int r) const { 33 | assert(0 <= l && l <= r && r <= n); 34 | if (l == r) return 0; // empty 35 | return get(r) - get(l); 36 | } 37 | 38 | void reset() { 39 | std::fill(f.begin(), f.end(), T(0)); 40 | } 41 | 42 | int n; 43 | vector f; 44 | }; 45 | // }}} 46 | -------------------------------------------------------------------------------- /DataStructure/Fenwick/Fenwick2D_smallN.h: -------------------------------------------------------------------------------- 1 | // 0-based index 2 | // Tested: 3 | // - https://www.spoj.com/problems/MATSUM/ 4 | // 5 | // Fenwick 2D, small N {{{ 6 | template< 7 | typename T // need to support +, - 8 | > struct Fenwick2D { 9 | Fenwick2D(int _n1, int _n2) : n1(_n1), n2(_n2), f(1+n1, vector (1+n2, T(0))) {} 10 | 11 | // a[x][y] += val 12 | void update(int x, int y, T val) { 13 | assert(0 <= x && x < n1); 14 | assert(0 <= y && y < n2); 15 | ++x; ++y; 16 | for (int u = x; u <= n1; u += u & -u) { 17 | for (int v = y; v <= n2; v += v & -v) { 18 | f[u][v] += val; 19 | } 20 | } 21 | } 22 | 23 | // return rect sum of [0, 0] -> [x-1, y-1] 24 | T get(int x, int y) const { 25 | assert(0 <= x && x <= n1); 26 | assert(0 <= y && y <= n2); 27 | T res(0); 28 | for (int u = x; u > 0; u -= u & -u) { 29 | for (int v = y; v > 0; v -= v & -v) { 30 | res += f[u][v]; 31 | } 32 | } 33 | return res; 34 | } 35 | 36 | // returns rect sum of [x1, y1] -> [x2-1, y2-1] 37 | T get(int x1, int y1, int x2, int y2) const { 38 | assert(0 <= x1 && x1 <= x2 && x2 <= n1); 39 | assert(0 <= y1 && y1 <= y2 && y2 <= n2); 40 | if (x1 == x2 || y1 == y2) return T(0); 41 | return get(x2, y2) - get(x1, y2) - get(x2, y1) + get(x1, y1); 42 | } 43 | 44 | int n1, n2; 45 | vector> f; 46 | }; 47 | // }}} 48 | -------------------------------------------------------------------------------- /DataStructure/Fenwick/PartiallyPersistentFenwick.h: -------------------------------------------------------------------------------- 1 | // NOTE: 2 | // - 0-based index 3 | // - for updates: time must be in increasing order 4 | // - Update: O(log), Get: O(log^2) 5 | // 6 | // Partially Persistent FenwickTree {{{ 7 | template< 8 | typename T // need to support operators + - < 9 | > struct PartiallyPersistentFenwick { 10 | PartiallyPersistentFenwick(int _n) : n(_n), f(_n + 1) { 11 | for (int i = 0; i <= n; ++i) { 12 | f[i].emplace_back(INT_MIN, T{}); 13 | } 14 | } 15 | 16 | // a[u] += val 17 | void update(int time, int u, T val) { 18 | assert(0 <= u && u < n); 19 | assert(last_updated_time <= time); 20 | last_updated_time = time; 21 | ++u; 22 | for (; u <= n; u += u & -u) { 23 | f[u].emplace_back(time, f[u].back().second + val); 24 | } 25 | } 26 | 27 | // return a[0] + .. + a[u-1] 28 | T get(int time, int u) const { 29 | assert(0 <= u && u <= n); 30 | T res{}; 31 | for (; u > 0; u -= u & -u) { 32 | auto it = lower_bound(f[u].begin(), f[u].end(), make_pair(time+1, T{})); 33 | res = res + prev(it)->second; 34 | } 35 | return res; 36 | } 37 | 38 | // return a[l] + .. + a[r-1] 39 | T get(int time, int l, int r) const { 40 | assert(0 <= l && l <= r && r <= n); 41 | if (l == r) return T{}; // empty 42 | return get(time, r) - get(time, l); 43 | } 44 | 45 | int n; 46 | int last_updated_time = INT_MIN; 47 | vector>> f; // (time, data) 48 | }; 49 | // }}} 50 | -------------------------------------------------------------------------------- /DataStructure/HeavyLight.cpp: -------------------------------------------------------------------------------- 1 | // Tested: 2 | // - http://codeforces.com/gym/100739/problem/G 3 | // 4 | // Notes: 5 | // - Index from 1 6 | // - dfn: vertex id --> position 7 | // --> for point query, only need to visit(dfn[u]) 8 | // --> for range query, use query(u, v) 9 | // Author: zimpha 10 | #include 11 | using namespace std; 12 | const int MN = 100111; 13 | vector G[MN]; 14 | int sz[MN], dep[MN], fa[MN]; 15 | int dfn[MN], top[MN]; 16 | int n, id; 17 | 18 | // Operations on segment tree 19 | int querySeg(int i, int l, int r, int u, int v) {return 0;} 20 | 21 | void dfs1(int u, int f = 0) { 22 | sz[u] = 1; fa[u] = f; 23 | for (auto &v: G[u]) if (v != f) { 24 | dep[v] = dep[u] + 1; 25 | dfs1(v, u); sz[u] += sz[v]; 26 | } 27 | } 28 | 29 | void dfs2(int u, int chain, int f = 0) { 30 | int son(-1); dfn[u] = ++id; top[u] = chain; 31 | for (auto &v: G[u]) if (v != f) { 32 | if (son == -1 || sz[son] < sz[v]) son = v; 33 | } 34 | if (~son) dfs2(son, chain, u); 35 | for (auto &v: G[u]) if (v != f && v != son) { 36 | dfs2(v, v, u); 37 | } 38 | } 39 | 40 | int query(int u, int v) { 41 | int res = 0; 42 | int fu = top[u], fv = top[v]; 43 | while (fu != fv) { 44 | if (dep[fu] < dep[fv]) swap(u, v), swap(fu, fv); 45 | res += querySeg(1, 1, n, dfn[fu], dfn[u]); 46 | u = fa[fu], fu = top[u]; 47 | } 48 | if (dep[u] > dep[v]) swap(u, v); 49 | res += querySeg(1, 1, n, dfn[u], dfn[v]); 50 | return res; 51 | } 52 | 53 | int main() { 54 | dfs1(1); 55 | id = 0; 56 | dfs2(1, 1); 57 | } 58 | 59 | -------------------------------------------------------------------------------- /DataStructure/LCA.h: -------------------------------------------------------------------------------- 1 | // LCA 2 | // Notes: 3 | // - Index from 0 4 | // - Cannot use for queries like min edge in path u -> v 5 | // 6 | // Tested: 7 | // - https://judge.yosupo.jp/problem/lca 8 | #include "RMQ.h" 9 | struct LCA { 10 | const int n; 11 | vector> adj; 12 | const int root; 13 | using P = pair; 14 | static P f(P x, P y) { return std::min(x, y); } 15 | 16 | LCA(int _n, const vector>& _adj, int _root) 17 | : n(_n), adj(_adj), root(_root) { 18 | assert(0 <= root && root < n); 19 | id.resize(n); 20 | depth.resize(n); 21 | order.reserve(2 * n); 22 | dfs(root, -1, 0); 23 | rmq = RMQ(order); 24 | } 25 | 26 | int lca(int u, int v) { 27 | assert(0 <= u && u < n); 28 | assert(0 <= v && v < n); 29 | 30 | int x = id[u], y = id[v]; 31 | if (x > y) std::swap(x, y); 32 | return rmq.get(x, y+1).second; 33 | } 34 | 35 | // private: 36 | vector id, depth; 37 | vector

order; 38 | RMQ rmq; 39 | 40 | void dfs(int u, int fu, int d) { 41 | id[u] = order.size(); 42 | depth[u] = d; 43 | order.emplace_back(d, u); 44 | for (int v : adj[u]) { 45 | if (v == fu) continue; 46 | dfs(v, u, d + 1); 47 | order.emplace_back(d, u); 48 | } 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /DataStructure/LCA_RMQ.h: -------------------------------------------------------------------------------- 1 | // L[i] = level 2 | // L[root] = -1 3 | // LCA[0][root] = -1 4 | const int MN = 100111; 5 | int V, LCA[22][MN], L[MN]; 6 | long long Rmax[22][MN]; 7 | #define LL long long 8 | void initLCA () { 9 | FOR (lg, 1, 19) { 10 | REP (i, V) { 11 | if (LCA[lg - 1][i] == -1) continue; 12 | LCA[lg][i] = LCA[lg - 1][LCA[lg - 1][i]]; 13 | Rmax[lg][i] = max (Rmax[lg - 1][LCA[lg - 1][i]], Rmax[lg - 1][i]); 14 | } 15 | } 16 | } 17 | 18 | LL query (LL a, LL b) { 19 | LL ret = 0; 20 | if (L[a] < L[b]) swap (a, b); 21 | 22 | FORD(lg,19,0) { 23 | if (LCA[lg][a] != -1 && L[LCA[lg][a]] >= L[b]) { 24 | ret = max (ret, Rmax[lg][a]); 25 | a = LCA[lg][a]; 26 | } 27 | } 28 | if (a == b) return ret; // if LCA, return a 29 | FORD(lg,19,0) { 30 | if (LCA[lg][a] != LCA[lg][b]) { 31 | ret = max (ret, Rmax[lg][a]); 32 | ret = max (ret, Rmax[lg][b]); 33 | a = LCA[lg][a]; 34 | b = LCA[lg][b]; 35 | } 36 | } 37 | ret = max (ret, Rmax[0][a]); 38 | ret = max (ret, Rmax[0][b]); 39 | return ret; // if LCA, return LCA[0][a] 40 | } 41 | 42 | -------------------------------------------------------------------------------- /DataStructure/OrderedSet.h: -------------------------------------------------------------------------------- 1 | // Copied from chemthan 2 | // 3 | // Usage: 4 | // 5 | // OrderedTree set; 6 | // set.init(MAX_VALUE); // Init set to store 0..n-1 7 | // set.upd(x, x, +1); // normally can just upd x = val (val is just for mapping of values) 8 | // set.find_by_order(k) // k from 1 9 | // 10 | // Tested: 11 | // - https://open.kattis.com/problems/lazylearner 12 | // - https://cses.fi/problemset/task/1076 13 | 14 | template 15 | struct OrderedTree { 16 | int n; 17 | vector a; 18 | num_t tot; 19 | vector x; 20 | 21 | void init(int _n) { 22 | n = _n; 23 | a.resize(n); 24 | for (int i = 0; i < n; i++) a[i] = 0; 25 | tot = 0; 26 | x.resize(n + 1); 27 | for (int i = 0; i <= n; i++) x[i] = 0; 28 | } 29 | 30 | void upd(int p, num_t val, num_t cnt) { 31 | assert(0 <= p && p < n); 32 | a[p] = val, tot += cnt; 33 | for (p++; p <= n; p += p & -p) { 34 | x[p] += cnt; 35 | } 36 | } 37 | 38 | // 1 <= k <= tot (tot = number of elements) 39 | num_t find_by_order(num_t k) { 40 | assert(0 <= k && k <= tot); 41 | if (!k) return -1; 42 | int p = 0; 43 | for (int i = __lg(n); i >= 0; i--) { 44 | if (p + (1 << i) <= n && x[p + (1 << i)] < k) { 45 | k -= x[p + (1 << i)]; 46 | p += 1 << i; 47 | } 48 | } 49 | return a[p]; 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /DataStructure/PersistentArray.h: -------------------------------------------------------------------------------- 1 | // PersistentArray 2 | // 3 | // Notes: 4 | // - Reduce mem -> decrease LOG 5 | // - Reduce time -> increase LOG 6 | // 7 | // Tested: 8 | // - https://codeforces.com/contest/707/problem/D 9 | template 10 | struct PersistentArray { 11 | static const int LOG = 4; 12 | static const int FULL_MASK = (1< child; 17 | Node(const T& _x) : x(_x) { 18 | std::fill(child.begin(), child.end(), nullptr); 19 | } 20 | Node(const Node& n) : x(n.x) { 21 | std::copy(n.child.begin(), n.child.end(), child.begin()); 22 | } 23 | }; 24 | 25 | // get p-th element in `t` version 26 | static T get(Node* t, int p) { 27 | if (t == NULL) return 0; 28 | return p ? get(t->child[p & FULL_MASK], p >> LOG) : t->x; 29 | } 30 | 31 | // set p-th element in `t` version to x, and return new version 32 | static Node* set(Node* t, int p, const T& x) { 33 | t = (t == NULL) ? new Node(0) : new Node(*t); 34 | if (p == 0) t->x = x; 35 | else { 36 | auto ptr = set(t->child[p & FULL_MASK], p >> LOG, x); 37 | t->child[p & FULL_MASK] = ptr; 38 | } 39 | return t; 40 | } 41 | 42 | // init a persistent array and return root node 43 | Node* build(const vector& v) { 44 | Node* root = NULL; 45 | for (int i = 0; i < (int) v.size(); i++) { 46 | root = set(root, i, v[i]); 47 | } 48 | return root; 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /DataStructure/RMQ.h: -------------------------------------------------------------------------------- 1 | // RMQ {{{ 2 | // 3 | // Sparse table 4 | // Usage: 5 | // RMQ st(v); 6 | // 7 | // Note: 8 | // - doesn't work for empty range 9 | // 10 | // Tested: 11 | // - https://judge.yosupo.jp/problem/staticrmq 12 | template struct RMQ { 13 | RMQ() = default; 14 | RMQ(const vector& v) : t{v}, n{(int) v.size()} { 15 | for (int k = 1; (1<> t; 33 | int n; 34 | }; 35 | template T _min(T a, T b) { return b < a ? b : a; } 36 | template T _max(T a, T b) { return a < b ? b : a; } 37 | // }}} 38 | -------------------------------------------------------------------------------- /DataStructure/STL/order_statistic.cpp: -------------------------------------------------------------------------------- 1 | #include // Common file 2 | #include // Including tree_order_statistics_node_update 3 | 4 | using namespace __gnu_pbds; 5 | 6 | // for multiset, change less -> less_equal 7 | typedef tree, rb_tree_tag, tree_order_statistics_node_update> ordered_set; 8 | 9 | int main() { 10 | ordered_set X; 11 | // X = {1, 2, 4, 8, 16} 12 | for(int i = 1; i <= 16; i *= 2) 13 | X.insert(i); 14 | cout << *X.find_by_order(0) << endl; // 1 15 | cout << *X.find_by_order(1) << endl; // 2 16 | cout << *X.find_by_order(2) << endl; // 4 17 | cout << *X.find_by_order(4) << endl; // 16 18 | cout << (X.end()==X.find_by_order(6)) << endl; // true 19 | 20 | cout< mp; 5 | // mp.reserve(N); // maybe use 2^x? 6 | // mp.max_load_factor(0.25); 7 | 8 | // Code copied from https://codeforces.com/contest/1006/submission/41804666 9 | #include 10 | using namespace __gnu_pbds; 11 | 12 | unsigned hash_f(unsigned x) { 13 | x = ((x >> 16) ^ x) * 0x45d9f3b; 14 | x = ((x >> 16) ^ x) * 0x45d9f3b; 15 | x = (x >> 16) ^ x; 16 | return x; 17 | } 18 | struct chash { 19 | int operator()(int x) const { return hash_f(x); } 20 | }; 21 | 22 | gp_hash_table mp; 23 | 24 | 25 | // alternative hash function: 26 | // Code copied from https://ideone.com/LhpILA 27 | const ll TIME = chrono::high_resolution_clock::now().time_since_epoch().count(); 28 | const ll SEED = (ll)(new ll); 29 | const ll RANDOM = TIME ^ SEED; 30 | const ll MOD = (int)1e9+7; 31 | const ll MUL = (int)1e6+3; 32 | 33 | struct chash{ 34 | ll operator()(ll x) const { return std::hash{}((x ^ RANDOM) % MOD * MUL); } 35 | }; 36 | -------------------------------------------------------------------------------- /DataStructure/STL/rope.cpp: -------------------------------------------------------------------------------- 1 | // Example usages: 2 | // - https://www.spoj.com/problems/AROPE/ 3 | // - https://www.spoj.com/problems/AROPE2/ 4 | // - (reverse substring) https://www.spoj.com/problems/AROPE3/ 5 | // -> maintain reverse string 6 | 7 | #include 8 | #include // Slow (balanced BST)!!! do not abuse 9 | using namespace std; 10 | using namespace __gnu_cxx; 11 | int main() { 12 | rope v; //use as usual STL container 13 | int n, m; 14 | cin >> n >> m; 15 | for(int i = 1; i <= n; ++i) 16 | v.push_back(i); //initialization 17 | int l, r; 18 | for(int i = 0; i < m; ++i) 19 | { 20 | cin >> l >> r; 21 | --l, --r; 22 | rope cur = v.substr(l, r - l + 1); 23 | v.erase(l, r - l + 1); 24 | // Note: if erase a single element, must use v.erase(i, 1). 25 | // There is another function v.erase(i) but it's wrong 26 | // https://codeforces.com/blog/entry/94213 27 | v.insert(v.mutable_begin(), cur); 28 | } 29 | for(rope ::iterator it = v.mutable_begin(); it != v.mutable_end(); ++it) 30 | cout << *it << " "; 31 | } 32 | -------------------------------------------------------------------------------- /DataStructure/STL/unordered_map_pair.h: -------------------------------------------------------------------------------- 1 | namespace std { 2 | template<> 3 | struct hash< pair > { 4 | public: 5 | size_t operator() (pair x) const { 6 | return x.first * 1000000009 + x.second; 7 | } 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /DataStructure/misc/ndvec.h: -------------------------------------------------------------------------------- 1 | // Copied from https://codeforces.com/blog/entry/76149 2 | 3 | // n-d vector {{{ 4 | template 5 | struct Vec : public vector> { 6 | static_assert(D >= 1, "Dimension must be positive"); 7 | template 8 | Vec(int n = 0, Args... args) : vector>(n, Vec (args...)) {} 9 | }; 10 | 11 | template 12 | struct Vec<1, T> : public vector { 13 | Vec(int n = 0, T val = T()) : vector (n, val) {} 14 | }; 15 | // }}} 16 | 17 | // Usage: 18 | { 19 | Vec<2, int> a(10, 50); // int a[10][50] initialized with zero 20 | Vec<3, double> b(10, 10, 10, 3.14); // double b[10][10][10] initialized with 3.14 21 | 22 | Vec<3, long long> c(5, 5); // the third dimension has no value yet 23 | c[0][0].push_back(100); // now c[0][0][0] has a value (100) but others don't 24 | 25 | Vec<4, int> d(10, 10); 26 | d[2][3].push_back(Vec<1, int>(100, 12345)); // now d[2][3][0] is a vector with 100 values of 12345 27 | 28 | Vec<1, string> e; // just blank vector of strings 29 | } 30 | -------------------------------------------------------------------------------- /DataStructure/misc/offset_vector.h: -------------------------------------------------------------------------------- 1 | template 2 | struct OffsetVector { 3 | // Index should be in [minIndex, maxIndex]. 4 | // minIndex and maxIndex can be negative. 5 | OffsetVector(int minIndex, int maxIndex) { 6 | x.resize(maxIndex - minIndex + 1); 7 | offset = minIndex; 8 | } 9 | 10 | V& operator [] (int index) { 11 | return x[index - offset]; 12 | } 13 | 14 | auto begin() { return x.begin(); } 15 | auto end() { return x.end(); } 16 | auto size() { return x.size(); } 17 | 18 | private: 19 | std::vector x; 20 | int offset; 21 | }; 22 | -------------------------------------------------------------------------------- /DataStructure/test/.gitignore: -------------------------------------------------------------------------------- 1 | in 2 | -------------------------------------------------------------------------------- /DataStructure/test/aizu_dsl_1_a_dsu.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_1_A" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../DSU/DisjointSet.h" 7 | 8 | int main() { 9 | ios::sync_with_stdio(0); cin.tie(0); 10 | int n, q; cin >> n >> q; 11 | DSU dsu(n); 12 | while (q--) { 13 | int typ, x, y; cin >> typ >> x >> y; 14 | if (typ == 0) dsu.merge(x, y); 15 | else cout << dsu.same_component(x, y) << '\n'; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /DataStructure/test/aizu_dsl_1_b_dsu_weighted.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_1_B" 2 | 3 | #include "../../template.h" 4 | #include "../DSU/DSU_weighted.h" 5 | 6 | void solve() { 7 | int n, q; cin >> n >> q; 8 | WeightedDSU dsu(n); 9 | while (q--) { 10 | int typ; cin >> typ; 11 | if (typ == 0) { 12 | int x, y, z; cin >> x >> y >> z; 13 | // f[y] = f[x] + z 14 | dsu.merge(x, y, z); 15 | } else { 16 | int x, y; cin >> x >> y; 17 | if (dsu.getRoot(x) == dsu.getRoot(y)) { 18 | cout << dsu.weight(y) - dsu.weight(x) << '\n'; 19 | } else { 20 | cout << "?\n"; 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /DataStructure/test/aizu_dsl_2_a_segment_tree_rmq_update.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_A" 2 | 3 | #include "../../template.h" 4 | #include "../SegTree.h" 5 | 6 | void solve() { 7 | int n, q; cin >> n >> q; 8 | SegTree st(n); 9 | while (q--) { 10 | int typ; cin >> typ; 11 | if (typ == 0) { 12 | int pos, val; cin >> pos >> val; 13 | st.set(pos, val); 14 | } else { 15 | int l, r; cin >> l >> r; 16 | cout << st.prod(l, r+1) << '\n'; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /DataStructure/test/aizu_dsl_2_b_fenwick_aizu.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_B" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../Fenwick/Fenwick.h" 7 | 8 | int main() { 9 | ios::sync_with_stdio(0); cin.tie(0); 10 | int n, q; cin >> n >> q; 11 | Fenwick bit(n); 12 | while (q--) { 13 | int typ, x, y; cin >> typ >> x >> y; 14 | --x; 15 | if (typ == 0) bit.update(x, y); 16 | else cout << bit.get(x, y) << '\n'; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /DataStructure/test/aizu_dsl_2_b_segment_tree_sum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_B" 2 | 3 | #include "../../template.h" 4 | #include "../SegTree.h" 5 | 6 | void solve() { 7 | int n, q; cin >> n >> q; 8 | SegTree st(n); 9 | while (q--) { 10 | int typ; cin >> typ; 11 | if (typ == 0) { 12 | int pos, val; cin >> pos >> val; 13 | --pos; 14 | st.set(pos, st.get(pos) + val); 15 | } else { 16 | int l, r; cin >> l >> r; 17 | --l; 18 | cout << st.prod(l, r) << '\n'; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /DataStructure/test/aizu_dsl_2_d_rangeset.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_D" 2 | 3 | #include "../../template.h" 4 | #include "../RangeSet.h" 5 | 6 | void solve() { 7 | int n, q; cin >> n >> q; 8 | 9 | // bits[b] contains set of elements with bit b == 1 10 | std::array, 31> bits; 11 | 12 | // Init all a[i] to 2^31 - 1 13 | for (int i = 0; i < 31; ++i) { 14 | bits[i].insert(0, n - 1); 15 | } 16 | 17 | while (q--) { 18 | int typ; cin >> typ; 19 | if (typ == 0) { 20 | int l, r, val; cin >> l >> r >> val; 21 | for (int bit = 0; bit < 31; ++bit) { 22 | if ((val >> bit) & 1) { 23 | bits[bit].insert(l, r); 24 | } else { 25 | bits[bit].erase(l, r); 26 | } 27 | } 28 | } else { 29 | int l; cin >> l; 30 | int res = 0; 31 | for (int bit = 0; bit < 31; ++bit) { 32 | res |= bits[bit].contains(l) << bit; 33 | } 34 | cout << res << '\n'; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /DataStructure/test/aizu_dsl_2_d_segment_tree_rangeset.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_D" 2 | 3 | #include "../../template.h" 4 | #include "../LazySegTree.h" 5 | 6 | void solve() { 7 | int n, q; cin >> n >> q; 8 | vector nodes; 9 | REP(i,n) nodes.push_back(RangeSetAddMinSumOps::S{0, INT_MAX, 1}); 10 | LazySegTree< 11 | RangeSetAddMinSumOps::S, 12 | RangeSetAddMinSumOps::op, 13 | RangeSetAddMinSumOps::e, 14 | RangeSetAddMinSumOps::F, 15 | RangeSetAddMinSumOps::mapping, 16 | RangeSetAddMinSumOps::composition, 17 | RangeSetAddMinSumOps::id 18 | > st(nodes); 19 | while (q--) { 20 | int typ; cin >> typ; 21 | if (typ == 0) { 22 | int l, r, val; cin >> l >> r >> val; 23 | st.apply(l, r+1, RangeSetAddMinSumOps::F { val, 0 }); 24 | } else { 25 | int l; cin >> l; 26 | cout << st.get(l).min << '\n'; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /DataStructure/test/aizu_dsl_2_e_segment_tree_rangeadd.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_E" 2 | 3 | #include "../../template.h" 4 | #include "../LazySegTree.h" 5 | 6 | void solve() { 7 | int n, q; cin >> n >> q; 8 | vector nodes; 9 | REP(i,n) nodes.push_back(RangeSetAddMinSumOps::S{0, 0, 1}); 10 | LazySegTree< 11 | RangeSetAddMinSumOps::S, 12 | RangeSetAddMinSumOps::op, 13 | RangeSetAddMinSumOps::e, 14 | RangeSetAddMinSumOps::F, 15 | RangeSetAddMinSumOps::mapping, 16 | RangeSetAddMinSumOps::composition, 17 | RangeSetAddMinSumOps::id 18 | > st(nodes); 19 | while (q--) { 20 | int typ; cin >> typ; 21 | if (typ == 0) { 22 | int l, r, val; cin >> l >> r >> val; 23 | --l; 24 | st.apply(l, r, RangeSetAddMinSumOps::F { RangeSetAddMinSumOps::NOT_SET, val }); 25 | } else { 26 | int l; cin >> l; 27 | --l; 28 | cout << st.get(l).sum << '\n'; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /DataStructure/test/aizu_dsl_2_f_segment_tree_rangesetmin.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_F" 2 | 3 | #include "../../template.h" 4 | #include "../LazySegTree.h" 5 | 6 | void solve() { 7 | int n, q; cin >> n >> q; 8 | vector nodes; 9 | REP(i,n) nodes.push_back(RangeSetAddMinSumOps::S{0, INT_MAX, 1}); 10 | LazySegTree< 11 | RangeSetAddMinSumOps::S, 12 | RangeSetAddMinSumOps::op, 13 | RangeSetAddMinSumOps::e, 14 | RangeSetAddMinSumOps::F, 15 | RangeSetAddMinSumOps::mapping, 16 | RangeSetAddMinSumOps::composition, 17 | RangeSetAddMinSumOps::id 18 | > st(nodes); 19 | while (q--) { 20 | int typ; cin >> typ; 21 | if (typ == 0) { 22 | int l, r, val; cin >> l >> r >> val; 23 | st.apply(l, r + 1, RangeSetAddMinSumOps::F { val, 0 }); 24 | } else { 25 | int l, r; cin >> l >> r; 26 | cout << st.prod(l, r + 1).min << '\n'; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /DataStructure/test/aizu_dsl_2_g_segment_tree_rangeaddsum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_G" 2 | 3 | #include "../../template.h" 4 | #include "../LazySegTree.h" 5 | 6 | void solve() { 7 | int n, q; cin >> n >> q; 8 | vector nodes; 9 | REP(i,n) nodes.push_back(RangeSetAddMinSumOps::S{0, 0, 1}); 10 | LazySegTree< 11 | RangeSetAddMinSumOps::S, 12 | RangeSetAddMinSumOps::op, 13 | RangeSetAddMinSumOps::e, 14 | RangeSetAddMinSumOps::F, 15 | RangeSetAddMinSumOps::mapping, 16 | RangeSetAddMinSumOps::composition, 17 | RangeSetAddMinSumOps::id 18 | > st(nodes); 19 | while (q--) { 20 | int typ; cin >> typ; 21 | if (typ == 0) { 22 | int l, r, val; cin >> l >> r >> val; 23 | --l; 24 | st.apply(l, r, RangeSetAddMinSumOps::F { RangeSetAddMinSumOps::NOT_SET, val }); 25 | } else { 26 | int l, r; cin >> l >> r; 27 | --l; 28 | cout << st.prod(l, r).sum << '\n'; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /DataStructure/test/aizu_dsl_2_h_segment_tree_rangeaddmin.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_H" 2 | 3 | #include "../../template.h" 4 | #include "../LazySegTree.h" 5 | 6 | void solve() { 7 | int n, q; cin >> n >> q; 8 | vector nodes; 9 | REP(i,n) nodes.push_back(RangeSetAddMinSumOps::S{0, 0, 1}); 10 | LazySegTree< 11 | RangeSetAddMinSumOps::S, 12 | RangeSetAddMinSumOps::op, 13 | RangeSetAddMinSumOps::e, 14 | RangeSetAddMinSumOps::F, 15 | RangeSetAddMinSumOps::mapping, 16 | RangeSetAddMinSumOps::composition, 17 | RangeSetAddMinSumOps::id 18 | > st(nodes); 19 | while (q--) { 20 | int typ; cin >> typ; 21 | if (typ == 0) { 22 | int l, r, val; cin >> l >> r >> val; 23 | ++r; 24 | st.apply(l, r, RangeSetAddMinSumOps::F { RangeSetAddMinSumOps::NOT_SET, val }); 25 | } else { 26 | int l, r; cin >> l >> r; 27 | ++r; 28 | cout << st.prod(l, r).min << '\n'; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /DataStructure/test/aizu_dsl_2_i_segment_tree_rangesetsum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_I" 2 | 3 | #include "../../template.h" 4 | #include "../LazySegTree.h" 5 | 6 | void solve() { 7 | int n, q; cin >> n >> q; 8 | vector nodes; 9 | REP(i,n) nodes.push_back(RangeSetAddMinSumOps::S{0, 0, 1}); 10 | LazySegTree< 11 | RangeSetAddMinSumOps::S, 12 | RangeSetAddMinSumOps::op, 13 | RangeSetAddMinSumOps::e, 14 | RangeSetAddMinSumOps::F, 15 | RangeSetAddMinSumOps::mapping, 16 | RangeSetAddMinSumOps::composition, 17 | RangeSetAddMinSumOps::id 18 | > st(nodes); 19 | while (q--) { 20 | int typ; cin >> typ; 21 | if (typ == 0) { 22 | int l, r, val; cin >> l >> r >> val; 23 | ++r; 24 | st.apply(l, r, RangeSetAddMinSumOps::F { val, 0 }); 25 | } else { 26 | int l, r; cin >> l >> r; 27 | ++r; 28 | cout << st.prod(l, r).sum << '\n'; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /DataStructure/test/aizu_dsl_4_a_range_set.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://onlinejudge.u-aizu.ac.jp/problems/DSL_4_A" 2 | 3 | #include "../../template.h" 4 | #include "../RangeSet.h" 5 | 6 | void solve() { 7 | int n; std::cin >> n; 8 | std::set xs; 9 | std::vector> rects(n); 10 | for (auto& [x1, y1, x2, y2] : rects) { 11 | std::cin >> x1 >> y1 >> x2 >> y2; 12 | xs.insert(x1); 13 | xs.insert(x2); 14 | } 15 | 16 | long long res = 0; 17 | for (auto it = std::next(xs.begin()); it != xs.end(); ++it) { 18 | int left = *std::prev(it); 19 | int right = *it; 20 | 21 | RangeSet rs; 22 | for (auto [x1, y1, x2, y2] : rects) { 23 | if (x1 <= left && x2 >= right) { 24 | rs.insert(y1, y2 - 1); 25 | } 26 | } 27 | res += (right - left) * (long long) rs.n_elements(); 28 | } 29 | std::cout << res << endl; 30 | } 31 | -------------------------------------------------------------------------------- /DataStructure/test/aizu_grl_5_c_hld_lca.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_C" 2 | 3 | #include "../../template.h" 4 | #include "../HeavyLight_adamant.h" 5 | 6 | void solve() { 7 | ios::sync_with_stdio(0); cin.tie(0); 8 | int n; cin >> n; 9 | vector> adj(n); 10 | REP(i,n) { 11 | int k; cin >> k; 12 | while (k--) { 13 | int j; cin >> j; 14 | adj[i].push_back(j); 15 | adj[j].push_back(i); 16 | } 17 | } 18 | 19 | HLD hld(adj, 0); 20 | 21 | int q; cin >> q; 22 | while (q--) { 23 | int u, v; cin >> u >> v; 24 | cout << hld.lca(u, v) << '\n'; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /DataStructure/test/aizu_grl_5_c_lca.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_C" 2 | 3 | #include "../../template.h" 4 | #include "../LCA.h" 5 | 6 | void solve() { 7 | ios::sync_with_stdio(0); cin.tie(0); 8 | int n; cin >> n; 9 | vector> adj(n); 10 | REP(i,n) { 11 | int k; cin >> k; 12 | while (k--) { 13 | int j; cin >> j; 14 | adj[i].push_back(j); 15 | adj[j].push_back(i); 16 | } 17 | } 18 | 19 | LCA lca(n, adj, 0); 20 | 21 | int q; cin >> q; 22 | while (q--) { 23 | int u, v; cin >> u >> v; 24 | cout << lca.lca(u, v) << '\n'; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /DataStructure/test/aizu_grl_5_d_hld_edge.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_D" 2 | 3 | #include "../../template.h" 4 | #include "../SegTree.h" 5 | #include "../HeavyLight_adamant.h" 6 | 7 | using ll = long long; 8 | 9 | void solve() { 10 | int n; cin >> n; 11 | vector> adj(n); 12 | REP(i,n) { 13 | int k; cin >> k; 14 | while (k--) { 15 | int j; cin >> j; 16 | adj[i].push_back(j); 17 | adj[j].push_back(i); 18 | } 19 | } 20 | 21 | HLD hld(adj, 0); 22 | SegTree st(n); 23 | 24 | int q; cin >> q; 25 | while (q--) { 26 | int typ; cin >> typ; 27 | if (typ == 0) { 28 | int u, val; cin >> u >> val; 29 | hld.apply_path(u, hld.parent[u], true, [&] (int l, int r) { 30 | st.set(l, st.get(l) + val); 31 | }); 32 | } else { 33 | int u; cin >> u; 34 | cout << hld.prod_path_commutative( 35 | 0, u, true, [&] (int l, int r) { 36 | return st.prod(l, r+1); 37 | }) << '\n'; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /DataStructure/test/area_of_union_of_rectangles.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/area_of_union_of_rectangles" 2 | 3 | #include 4 | using namespace std; 5 | #include "../misc/area_of_union_of_rectangles.h" 6 | using namespace area_of_union_of_rectangles; 7 | 8 | int main() { 9 | int n; cin >> n; 10 | vector rects(n); 11 | for (auto& r : rects) cin >> r; 12 | cout << solve(rects) << endl; 13 | } 14 | -------------------------------------------------------------------------------- /DataStructure/test/binary_trie.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/set_xor_min" 2 | 3 | #include "../../template.h" 4 | #include "../BinaryTrie.h" 5 | 6 | void solve() { 7 | BinaryTrie trie; 8 | int q; cin >> q; 9 | while (q--) { 10 | int typ, x; cin >> typ >> x; 11 | if (typ == 0) { 12 | int has = trie.count(x); 13 | if (has == 0) trie.insert(x); 14 | } else if (typ == 1) { 15 | int has = trie.count(x); 16 | if (has == 1) trie.remove(x); 17 | } 18 | else cout << trie.min_element(x).first << '\n'; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /DataStructure/test/dsu.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/unionfind" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../DSU/DisjointSet.h" 7 | 8 | int32_t main() { 9 | ios::sync_with_stdio(0); cin.tie(0); 10 | int n, q; cin >> n >> q; 11 | DSU dsu(n); 12 | while (q--) { 13 | int typ, u, v; cin >> typ >> u >> v; 14 | if (typ == 0) dsu.merge(u, v); 15 | else { 16 | cout << (dsu.getRoot(u) == dsu.getRoot(v) ? 1 : 0) << '\n'; 17 | } 18 | } 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /DataStructure/test/fenwick.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/static_range_sum" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../Fenwick/Fenwick.h" 7 | #include "../../buffered_reader.h" 8 | 9 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 10 | 11 | int32_t main() { 12 | ios::sync_with_stdio(0); cin.tie(0); 13 | int n = IO::get(); 14 | int q = IO::get(); 15 | 16 | Fenwick f(n); 17 | REP(i,n) { 18 | int x = IO::get(); 19 | f.update(i, x); 20 | } 21 | 22 | while (q--) { 23 | int l = IO::get(); 24 | int r = IO::get(); 25 | cout << f.get(l, r) << '\n'; 26 | } 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /DataStructure/test/fenwick_2d_pointaddrectsum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/point_add_rectangle_sum" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../Fenwick/Fenwick2D.h" 7 | 8 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 9 | 10 | int32_t main() { 11 | ios::sync_with_stdio(0); cin.tie(0); 12 | int n, q; cin >> n >> q; 13 | 14 | vector> queries; 15 | REP(i,n) { 16 | int x, y, val; cin >> x >> y >> val; 17 | queries.push_back({Query::ADD, x, y, -1, -1, val}); 18 | } 19 | 20 | REP(i,q) { 21 | int typ; cin >> typ; 22 | if (typ == 0) { 23 | int x, y, val; cin >> x >> y >> val; 24 | queries.push_back({Query::ADD, x, y, -1, -1, val}); 25 | } else { 26 | int x, y, x2, y2; cin >> x >> y >> x2 >> y2; 27 | queries.push_back({Query::QUERY, x, y, x2, y2, 0}); 28 | } 29 | } 30 | 31 | Fenwick2D f; 32 | auto res = f.solve(queries); 33 | for (auto r : res) cout << r << '\n'; 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /DataStructure/test/fenwick_2d_rectsum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/rectangle_sum" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../Fenwick/Fenwick2D.h" 7 | 8 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 9 | 10 | int32_t main() { 11 | ios::sync_with_stdio(0); cin.tie(0); 12 | int n, q; cin >> n >> q; 13 | 14 | vector> queries; 15 | REP(i,n) { 16 | int x, y, val; cin >> x >> y >> val; 17 | queries.push_back({Query::ADD, x, y, -1, -1, val}); 18 | } 19 | 20 | REP(i,q) { 21 | int x, y, x2, y2; cin >> x >> y >> x2 >> y2; 22 | queries.push_back({Query::QUERY, x, y, x2, y2, 0}); 23 | } 24 | 25 | Fenwick2D f; 26 | auto res = f.solve(queries); 27 | for (auto r : res) cout << r << '\n'; 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /DataStructure/test/fenwick_pointaddrangesum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/point_add_range_sum" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../Fenwick/Fenwick.h" 7 | #include "../../buffered_reader.h" 8 | 9 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 10 | 11 | int32_t main() { 12 | ios::sync_with_stdio(0); cin.tie(0); 13 | int n = IO::get(); 14 | int q = IO::get(); 15 | 16 | Fenwick f(n); 17 | REP(i,n) { 18 | int x = IO::get(); 19 | f.update(i, x); 20 | } 21 | 22 | while (q--) { 23 | int typ = IO::get(); 24 | if (typ == 0) { 25 | int u = IO::get(); 26 | int val = IO::get(); 27 | f.update(u, val); 28 | } else if (typ == 1) { 29 | int l = IO::get(); 30 | int r = IO::get(); 31 | cout << f.get(l, r) << '\n'; 32 | } else { 33 | assert(false); 34 | } 35 | } 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /DataStructure/test/hld_lca.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/lca" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../HeavyLight_adamant.h" 7 | #include "../../buffered_reader.h" 8 | 9 | #define FOR(i, a, b) for (int i = (a), _##i = (b); i <= _##i; ++i) 10 | 11 | int32_t main() { 12 | ios::sync_with_stdio(0); cin.tie(0); 13 | int n = IO::get(); 14 | int q = IO::get(); 15 | vector> adj(n); 16 | FOR(i,1,n-1) { 17 | int pi = IO::get(); 18 | adj[pi].push_back(i); 19 | } 20 | 21 | HLD hld(adj, 0); 22 | 23 | while (q--) { 24 | int u = IO::get(); 25 | int v = IO::get(); 26 | 27 | cout << hld.lca(u, v) << '\n'; 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /DataStructure/test/hld_vertexaddpathsum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/vertex_add_path_sum" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../SegTree.h" 7 | #include "../HeavyLight_adamant.h" 8 | 9 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 10 | 11 | int32_t main() { 12 | ios::sync_with_stdio(0); cin.tie(0); 13 | int n, q; cin >> n >> q; 14 | vector a(n); 15 | REP(i,n) cin >> a[i]; 16 | 17 | vector> g(n); 18 | REP(i,n-1) { 19 | int u, v; cin >> u >> v; 20 | g[u].push_back(v); 21 | g[v].push_back(u); 22 | } 23 | 24 | HLD hld(g, 0); 25 | 26 | vector nodes; 27 | REP(i,n) nodes.push_back(a[hld.order[i]]); 28 | 29 | SegTree tree(nodes); 30 | 31 | while (q--) { 32 | int typ; cin >> typ; 33 | if (typ == 0) { 34 | int p, x; cin >> p >> x; 35 | tree.set(hld.in[p], tree.get(hld.in[p]) + x); 36 | } else { 37 | int u, v; cin >> u >> v; 38 | cout << hld.prod_path_commutative ( 39 | u, v, false, [&] (int l, int r) { 40 | return tree.prod(l, r+1); 41 | }) << '\n'; 42 | } 43 | } 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /DataStructure/test/hld_vertexaddsubtreesum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/vertex_add_subtree_sum" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../SegTree.h" 7 | #include "../HeavyLight_adamant.h" 8 | 9 | #define FOR(i, a, b) for (int i = (a), _##i = (b); i <= _##i; ++i) 10 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 11 | 12 | int32_t main() { 13 | ios::sync_with_stdio(0); cin.tie(0); 14 | int n, q; cin >> n >> q; 15 | vector a(n); 16 | REP(i,n) cin >> a[i]; 17 | 18 | vector> g(n); 19 | FOR(i,1,n-1) { 20 | int p; cin >> p; 21 | g[p].push_back(i); 22 | } 23 | 24 | HLD hld(g, 0); 25 | 26 | vector nodes; 27 | REP(i,n) { 28 | nodes.push_back(a[hld.order[i]]); 29 | } 30 | SegTree tree(nodes); 31 | 32 | while (q--) { 33 | int typ; cin >> typ; 34 | if (typ == 0) { 35 | int p, x; cin >> p >> x; 36 | tree.set(hld.in[p], tree.get(hld.in[p]) + x); 37 | } else { 38 | int u; cin >> u; 39 | cout << hld.prod_subtree_commutative ( 40 | u, false, 41 | [&] (int l, int r) { 42 | return tree.prod(l, r + 1); 43 | }) << '\n'; 44 | } 45 | } 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /DataStructure/test/lca.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/lca" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../LCA.h" 7 | #include "../../buffered_reader.h" 8 | 9 | #define FOR(i, a, b) for (int i = (a), _##i = (b); i <= _##i; ++i) 10 | 11 | int32_t main() { 12 | ios::sync_with_stdio(0); cin.tie(0); 13 | int n = IO::get(); 14 | int q = IO::get(); 15 | vector> adj(n); 16 | FOR(i,1,n-1) { 17 | int pi = IO::get(); 18 | adj[i].push_back(pi); 19 | adj[pi].push_back(i); 20 | } 21 | 22 | LCA lca(n, adj, 0); 23 | 24 | while (q--) { 25 | int u = IO::get(); 26 | int v = IO::get(); 27 | 28 | cout << lca.lca(u, v) << '\n'; 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /DataStructure/test/li_chao_seg_tree_lineaddgetmin.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/line_add_get_min" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../LiChaoSegTree.h" 7 | 8 | using ll = long long; 9 | struct Query { 10 | int typ; 11 | ll a, b; 12 | }; 13 | 14 | int32_t main() { 15 | ios::sync_with_stdio(0); cin.tie(0); 16 | int n, q; cin >> n >> q; 17 | 18 | vector queries; 19 | vector xs; 20 | 21 | while (n--) { 22 | ll a, b; cin >> a >> b; 23 | queries.push_back({0, a, b}); 24 | } 25 | 26 | while (q--) { 27 | int typ; cin >> typ; 28 | if (typ == 0) { 29 | ll a, b; cin >> a >> b; 30 | queries.push_back({0, a, b}); 31 | } else { 32 | ll x; cin >> x; 33 | queries.push_back({1, x, 0}); 34 | xs.push_back(x); 35 | } 36 | } 37 | LiChao tree(xs); 38 | 39 | for (auto [typ, a, b] : queries) { 40 | if (typ == 0) { 41 | tree.add_line(a, b, 0); 42 | } else { 43 | auto res = tree.get(a); 44 | assert(res.is_valid); 45 | cout << (long long) res.minval << '\n'; 46 | } 47 | } 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /DataStructure/test/li_chao_seg_tree_segaddgetmin.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/segment_add_get_min" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../LiChaoSegTree.h" 7 | 8 | using ll = long long; 9 | struct Query { 10 | int typ; 11 | ll l, r, a, b; 12 | }; 13 | 14 | int32_t main() { 15 | ios::sync_with_stdio(0); cin.tie(0); 16 | int n, q; cin >> n >> q; 17 | 18 | vector queries; 19 | vector xs; 20 | 21 | while (n--) { 22 | ll l, r, a, b; cin >> l >> r >> a >> b; 23 | queries.push_back({0, l, r, a, b}); 24 | } 25 | 26 | while (q--) { 27 | int typ; cin >> typ; 28 | if (typ == 0) { 29 | ll l, r, a, b; cin >> l >> r >> a >> b; 30 | queries.push_back({0, l, r, a, b}); 31 | } else { 32 | ll x; cin >> x; 33 | queries.push_back({1, x, 0, 0, 0}); 34 | xs.push_back(x); 35 | } 36 | } 37 | LiChao tree(xs); 38 | 39 | for (auto [typ, l, r, a, b] : queries) { 40 | if (typ == 0) { 41 | tree.add_segment(l, r, a, b, 0); 42 | } else { 43 | auto res = tree.get(l); 44 | if (res.is_valid) { 45 | cout << (long long) res.minval << '\n'; 46 | } else { 47 | cout << "INFINITY\n"; 48 | } 49 | } 50 | } 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /DataStructure/test/link_cut_tree_addpathsum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/dynamic_tree_vertex_add_path_sum" 2 | 3 | #include 4 | using namespace std; 5 | 6 | using T = long long; 7 | #include "../LinkCutTree.h" 8 | 9 | #define FOR(i, a, b) for (int i = (a), _##i = (b); i <= _##i; ++i) 10 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 11 | 12 | int32_t main() { 13 | ios::sync_with_stdio(0); cin.tie(0); 14 | 15 | int n, q; cin >> n >> q; 16 | LinkCut tree(n); 17 | FOR(i,1,n) { 18 | int x; cin >> x; 19 | tree.set(i, x); 20 | } 21 | REP(i,n-1) { 22 | int u, v; cin >> u >> v; 23 | ++u; ++v; 24 | tree.link(u, v); 25 | } 26 | 27 | while (q--) { 28 | int typ; cin >> typ; 29 | if (typ == 0) { // delete (u, v), add(w, x) 30 | int u, v, w, x; cin >> u >> v >> w >> x; 31 | ++u; ++v; 32 | ++w; ++x; 33 | tree.cut(u, v); 34 | tree.link(w, x); 35 | } else if (typ == 1) { // a[p] += x 36 | int p, x; cin >> p >> x; 37 | ++p; 38 | tree.set(p, tree.get(p) + x); 39 | } else if (typ == 2) { // get sum of path u -> v 40 | int u, v; cin >> u >> v; 41 | ++u; ++v; 42 | cout << tree.getPath(u, v) << '\n'; 43 | } 44 | } 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /DataStructure/test/link_cut_tree_vertexaddsubtreesum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/dynamic_tree_vertex_add_subtree_sum" 2 | 3 | #include 4 | using namespace std; 5 | 6 | using T = long long; 7 | #include "../LinkCutTree.h" 8 | 9 | #define FOR(i, a, b) for (int i = (a), _##i = (b); i <= _##i; ++i) 10 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 11 | 12 | int32_t main() { 13 | ios::sync_with_stdio(0); cin.tie(0); 14 | 15 | int n, q; cin >> n >> q; 16 | LinkCut tree(n); 17 | FOR(i,1,n) { 18 | int x; cin >> x; 19 | tree.set(i, x); 20 | } 21 | REP(i,n-1) { 22 | int u, v; cin >> u >> v; 23 | ++u; ++v; 24 | tree.link(u, v); 25 | } 26 | 27 | while (q--) { 28 | int typ; cin >> typ; 29 | if (typ == 0) { // delete (u, v), add(w, x) 30 | int u, v, w, x; cin >> u >> v >> w >> x; 31 | ++u; ++v; 32 | ++w; ++x; 33 | tree.cut(u, v); 34 | tree.link(w, x); 35 | } else if (typ == 1) { // a[p] += x 36 | int p, x; cin >> p >> x; 37 | ++p; 38 | tree.set(p, tree.get(p) + x); 39 | } else if (typ == 2) { // get sum of subtree(u). v is parent of u 40 | int u, v; cin >> u >> v; 41 | ++u; ++v; 42 | cout << tree.getSubtree(u, v) << '\n'; 43 | } 44 | } 45 | return 0; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /DataStructure/test/mo_algorithm.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/static_range_sum" 2 | 3 | #include "../../template.h" 4 | #include "../Mo/MoAlgorithm.h" 5 | 6 | void solve() { 7 | int n, q; cin >> n >> q; 8 | vector a(n); REP(i,n) cin >> a[i]; 9 | 10 | vector queries(q); 11 | REP(i,q) { 12 | cin >> queries[i].l >> queries[i].r; 13 | queries[i].r--; 14 | } 15 | 16 | int64_t sum = 0; 17 | auto add = [&] (int id) { sum += a[id]; }; 18 | auto rem = [&] (int id) { sum -= a[id]; }; 19 | auto get = [&] ([[maybe_unused]] const Query& _) { return sum; }; 20 | 21 | auto res = mo 22 | (n, queries, add, rem, get); 23 | for (auto r : res) cout << r << '\n'; 24 | } 25 | -------------------------------------------------------------------------------- /DataStructure/test/mo_algorithm_with_undo.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/static_range_sum" 2 | 3 | #include "../../template.h" 4 | #include "../Mo/MoAlgorithmWithUndo.h" 5 | 6 | void solve() { 7 | int n, q; cin >> n >> q; 8 | vector a(n); REP(i,n) cin >> a[i]; 9 | 10 | vector queries(q); 11 | REP(i,q) { 12 | cin >> queries[i].l >> queries[i].r; 13 | queries[i].r--; 14 | } 15 | 16 | int64_t sum = 0; 17 | stack nums; 18 | 19 | auto add = [&] (int id) { 20 | sum += a[id]; 21 | nums.push(a[id]); 22 | }; 23 | auto undo = [&] () { 24 | sum -= nums.top(); 25 | nums.pop(); 26 | }; 27 | auto get = [&] ([[maybe_unused]] const Query& _) { 28 | return sum; 29 | }; 30 | 31 | auto res = mo_with_undo 32 | (n, queries, add, undo, get); 33 | for (auto r : res) cout << r << '\n'; 34 | } 35 | -------------------------------------------------------------------------------- /DataStructure/test/persistent_dsu.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/persistent_unionfind" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../DSU/DSU_persistent.h" 7 | 8 | int32_t main() { 9 | ios::sync_with_stdio(0); cin.tie(0); 10 | int n, q; cin >> n >> q; 11 | 12 | PersistentDSU dsu(n); 13 | 14 | while (q--) { 15 | int typ, version; cin >> typ >> version; 16 | int u, v; cin >> u >> v; 17 | 18 | if (typ == 0) { 19 | dsu.merge(version + 1, u, v); 20 | } else { 21 | // create extra version, since the input format requires it.. 22 | dsu.merge(version + 1, 0, 0); 23 | cout << dsu.same_component(version + 1, u, v) << '\n'; 24 | } 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /DataStructure/test/persistent_fenwick_tree_rmq.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/staticrmq" 2 | #include "../../template.h" 3 | #include "../Fenwick/PartiallyPersistentFenwick.h" 4 | 5 | struct Data { 6 | int x; 7 | Data() : x(INT_MAX) {} 8 | Data(int _x) : x(_x) {} 9 | }; 10 | Data operator + (const Data& a, const Data& b) { 11 | return Data{min(a.x, b.x)}; 12 | } 13 | bool operator < (const Data&, const Data&) { 14 | return false; 15 | } 16 | 17 | void solve() { 18 | int n, q; cin >> n >> q; 19 | vector a(n); 20 | REP(i,n) cin >> a[i]; 21 | 22 | PartiallyPersistentFenwick fen(n); 23 | FORD(i,n-1,0) fen.update(n-i, i, Data{a[i]}); 24 | 25 | while (q--) { 26 | int l, r; cin >> l >> r; 27 | auto res = fen.get(n-l, r); 28 | cout << res.x << '\n'; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /DataStructure/test/rmq.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/staticrmq" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../RMQ.h" 7 | #include "../../buffered_reader.h" 8 | 9 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 10 | 11 | int32_t main() { 12 | ios::sync_with_stdio(0); cin.tie(0); 13 | int n, q; cin >> n >> q; 14 | vector a(n); 15 | REP(i,n) cin >> a[i]; 16 | 17 | RMQ st(a); 18 | while (q--) { 19 | int l, r; cin >> l >> r; 20 | cout << st.get(l, r) << '\n'; 21 | } 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /DataStructure/test/segment_tree_pointaddrangesum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/point_add_range_sum" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../SegTree.h" 7 | #include "../../buffered_reader.h" 8 | 9 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 10 | 11 | int32_t main() { 12 | ios::sync_with_stdio(0); cin.tie(0); 13 | int n, q; cin >> n >> q; 14 | vector a(n); 15 | for (auto& x : a) cin >> x; 16 | 17 | SegTree seg_tree(a); 18 | 19 | while (q--) { 20 | int typ; cin >> typ; 21 | if (typ == 0) { 22 | int pos, val; cin >> pos >> val; 23 | seg_tree.set(pos, seg_tree.get(pos) + val); 24 | } else { 25 | int l, r; cin >> l >> r; 26 | cout << seg_tree.prod(l, r) << '\n'; 27 | } 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /DataStructure/test/segment_tree_pointsetrangecomposite.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/point_set_range_composite" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../SegTree.h" 7 | #include "../../Math/modint.h" 8 | #include "../../buffered_reader.h" 9 | 10 | using modular = ModInt<998244353>; 11 | 12 | struct Func { 13 | modular a, b; 14 | }; 15 | 16 | Func op(Func l, Func r) { 17 | return Func{ 18 | l.a * r.a, 19 | r.a * l.b + r.b 20 | }; 21 | } 22 | Func e() { 23 | return Func{1, 0}; 24 | } 25 | 26 | int32_t main() { 27 | ios::sync_with_stdio(0); cin.tie(0); 28 | int n = IO::get(); 29 | int q = IO::get(); 30 | vector funcs(n); 31 | for (auto& f : funcs) { 32 | int a = IO::get(); 33 | int b = IO::get(); 34 | f = {a, b}; 35 | } 36 | 37 | SegTree seg_tree(funcs); 38 | while (q--) { 39 | int typ = IO::get(); 40 | if (typ == 0) { 41 | int pos = IO::get(); 42 | int a = IO::get(); 43 | int b = IO::get(); 44 | seg_tree.set(pos, {a, b}); 45 | } else { 46 | int l = IO::get(); 47 | int r = IO::get(); 48 | auto f = seg_tree.prod(l, r); 49 | modular x(IO::get()); 50 | cout << f.a * x + f.b << '\n'; 51 | } 52 | } 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /DataStructure/test/segment_tree_staticrmq.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/staticrmq" 2 | #include 3 | using namespace std; 4 | 5 | #include "../SegTree.h" 6 | 7 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 8 | 9 | int32_t main() { 10 | ios::sync_with_stdio(0); cin.tie(0); 11 | int n, q; cin >> n >> q; 12 | vector a(n); 13 | REP(i,n) cin >> a[i]; 14 | 15 | SegTree st(a); 16 | while (q--) { 17 | int l, r; cin >> l >> r; 18 | cout << st.prod(l, r) << '\n'; 19 | } 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /DataStructure/test/wavelet_matrix_rangekthsmallest.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/range_kth_smallest" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../WaveletMatrix.h" 7 | #include "../../buffered_reader.h" 8 | 9 | int32_t main() { 10 | ios::sync_with_stdio(0); cin.tie(0); 11 | int n, q; cin >> n >> q; 12 | vector a(n); 13 | for (int& x : a) cin >> x; 14 | 15 | WaveletMatrix wm(a); 16 | while (q--) { 17 | int l, r, k; cin >> l >> r >> k; 18 | cout << wm.k_th(l, r, k) << '\n'; 19 | } 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /DataStructure/test/wavelet_matrix_staticrangefreq.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/static_range_frequency" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../WaveletMatrix.h" 7 | 8 | int32_t main() { 9 | ios::sync_with_stdio(0); cin.tie(0); 10 | int n, q; cin >> n >> q; 11 | vector a(n); 12 | for (int& x : a) cin >> x; 13 | 14 | WaveletMatrix wm(a); 15 | while (q--) { 16 | int l, r, x; cin >> l >> r >> x; 17 | cout << wm.range_count(l, r, x, x+1) << '\n'; 18 | } 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /DataStructure/test/yosupo_hld_kth_vertex_on_path.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/jump_on_tree" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../HeavyLight_adamant.h" 7 | #include "../../buffered_reader.h" 8 | 9 | #define FOR(i, a, b) for (int i = (a), _##i = (b); i <= _##i; ++i) 10 | 11 | int32_t main() { 12 | ios::sync_with_stdio(0); cin.tie(0); 13 | int n = IO::get(); 14 | int q = IO::get(); 15 | vector> adj(n); 16 | for (int i = 0; i < n-1; ++i) { 17 | int u = IO::get(); 18 | int v = IO::get(); 19 | adj[u].push_back(v); 20 | adj[v].push_back(u); 21 | } 22 | 23 | HLD hld(adj, 0); 24 | 25 | while (q--) { 26 | int u = IO::get(); 27 | int v = IO::get(); 28 | int k = IO::get(); 29 | cout << hld.kth_vertex_on_path(u, v, k) << '\n'; 30 | } 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /DataStructure/test/yosupo_rangereversesum_splay.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/range_reverse_range_sum" 2 | 3 | #include "../../template.h" 4 | #include "../splay_tree.h" 5 | 6 | using S = int64_t; 7 | using F = bool; 8 | using Node = node_t; 9 | 10 | S op(S left, int key, S right) { 11 | return left + key + right; 12 | } 13 | pair e() { return {0, 0}; } 14 | pair mapping([[maybe_unused]] F f, Node* node) { 15 | return {node->key, node->data}; 16 | } 17 | F composition([[maybe_unused]] F f, [[maybe_unused]] F g) { return false; } 18 | F id() { return false; } 19 | 20 | void solve() { 21 | int n, q; cin >> n >> q; 22 | vector a(n); REP(i,n) cin >> a[i]; 23 | SplayTreeById tree(a); 24 | 25 | while (q--) { 26 | int typ; cin >> typ; 27 | int l, r; cin >> l >> r; 28 | 29 | if (typ == 0) tree.reverse(l, r); 30 | else { 31 | cout << tree.prod(l, r) << '\n'; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /DataStructure/test/yukicoder_674_range_set.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://yukicoder.me/problems/no/674" 2 | 3 | #include "../../template.h" 4 | #include "../RangeSet.h" 5 | 6 | void solve() { 7 | long long d; 8 | int q; 9 | std::cin >> d >> q; 10 | 11 | long long ans = 0; 12 | RangeSet set; 13 | while (q --> 0) { 14 | long long l, r; 15 | std::cin >> l >> r; 16 | set.insert(l, r); 17 | auto lr = set.find_range(l); 18 | if (lr != set.ranges.end()) { 19 | auto [nl, nr] = *lr; 20 | ans = std::max(ans, nr - nl + 1LL); 21 | } 22 | std::cout << ans << '\n'; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Geometry/.gitignore: -------------------------------------------------------------------------------- 1 | # compiled files 2 | basic 3 | polygon 4 | circle 5 | misc 6 | 7 | # Halim code 8 | ch7_0* -------------------------------------------------------------------------------- /Geometry/RectInRect.h: -------------------------------------------------------------------------------- 1 | // Checks if rectangle of sides x,y fits inside one of sides X,Y 2 | // Not tested with doubles but should work fine :) 3 | // Code as written rejects rectangles that just touch. 4 | bool rect_in_rect(int X, int Y, int x, int y) { 5 | if (Y > X) swap(Y, X); 6 | if (y > x) swap(y, x); 7 | double diagonal = sqrt(double(X)*X + double(Y)*Y); 8 | if (x < X && y < Y) return true; 9 | else if (y >= Y || x >= diagonal) return false; 10 | else { 11 | double w, theta, tMin = PI/4, tMax = PI/2; 12 | while (tMax - tMin > EPS) { 13 | theta = (tMax + tMin)/2.0; 14 | w = (Y-x*cos(theta))/sin(theta); 15 | if (w < 0 || x * sin(theta) + w * cos(theta) < X) tMin = theta; 16 | else tMax = theta; 17 | } 18 | return (w > y); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Geometry/segment_union.h: -------------------------------------------------------------------------------- 1 | double segment_union(vector< pair > segs) { 2 | int n = SZ(segs); 3 | vector< pair > x(n*2); 4 | REP(i,n) { 5 | x[i*2] = make_pair(segs[i].first, false); 6 | x[i*2+1] = make_pair(segs[i].second, true); 7 | } 8 | sort(x.begin(), x.end()); 9 | 10 | double res = 0.0; 11 | int c = 0; 12 | REP(i,n*2) { 13 | if (c && i) res += x[i].first - x[i-1].first; 14 | if (x[i].second) ++c; 15 | else --c; 16 | } 17 | return res; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /Geometry/soddy_circles.txt: -------------------------------------------------------------------------------- 1 | // Tested: 2 | // - https://www.e-olymp.com/en/problems/269 (inner) 3 | 4 | Given 3 mutually tangent circles. Find inner circle (touching all 3) and outer circle (touching all 3). 5 | The radius is given by: 6 | k4 = |k1 + k2 + k3 +- 2*sqrt(k1*k2 + k2*k3 + k3*k1)| 7 | where ki = 1/ri 8 | Minus --> Outer 9 | Plus --> Inner 10 | 11 | Special cases: 12 | - If 1 circle --> line, change ki to 0 --> k4 = k1 + k2 +- 2*sqrt(k1*k2) 13 | 14 | -------------------------------------------------------------------------------- /Geometry/spherical.h: -------------------------------------------------------------------------------- 1 | struct Point3 { 2 | double x, y, z; 3 | 4 | Point3(Spherical P) { 5 | x = P.r * cos(P.theta) * sin(P.phi); 6 | y = P.r * sin(P.theta) * sin(P.phi); 7 | z = P.r * cos(P.phi); 8 | } 9 | }; 10 | 11 | // http://mathworld.wolfram.com/images/eps-gif/SphericalCoordinates_1201.gif 12 | struct Spherical { 13 | double r, 14 | theta, // 0 <= theta < 2*PI 15 | phi; // 0 <= phi <= PI 16 | 17 | Spherical(Point3 P) { 18 | r = sqrt(P.x*P.x + P.y*P.y + P.z*P.z); 19 | theta = atan(P.y / P.x); if (theta < 0) theta += 2 * PI; 20 | phi = acos(P.z / r); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_1_a_basic_projection.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | 6 | void solve() { 7 | cout << (fixed) << setprecision(10); 8 | Point a, b; cin >> a >> b; 9 | int q; cin >> q; 10 | while (q--) { 11 | Point p; cin >> p; 12 | Point projection; 13 | distToLine(p, a, b, projection); 14 | cout << projection << '\n'; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_1_b_basic_reflection.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | 6 | #define ERROR 1e-9 7 | 8 | void solve() { 9 | cout << (fixed) << setprecision(10); 10 | Point a, b; cin >> a >> b; 11 | int q; cin >> q; 12 | while (q--) { 13 | Point p; cin >> p; 14 | Point projection; 15 | distToLine(p, a, b, projection); 16 | Point reflection = projection * 2 - p; 17 | cout << reflection << '\n'; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_1_c_basic_ccw.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | 6 | void solve() { 7 | Point a, b; cin >> a >> b; 8 | int q; cin >> q; 9 | while (q--) { 10 | Point c; cin >> c; 11 | auto t = ccw(a, b, c); 12 | if (t == 0) { 13 | if (onSegment(a, b, c)) cout << "ON_SEGMENT\n"; 14 | else if (onSegment(c, b, a)) cout << "ONLINE_BACK\n"; 15 | else cout << "ONLINE_FRONT\n"; 16 | } else if (t < 0) cout << "CLOCKWISE\n"; 17 | else cout << "COUNTER_CLOCKWISE\n"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_2_a_basic_line.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | 6 | bool orthogonal(const Line& l1, const Line& l2) { 7 | Point a(l1.a, l1.b); 8 | Point b(l2.a, l2.b); 9 | return cmp(a * b, 0) == 0; 10 | } 11 | 12 | void solve() { 13 | int q; cin >> q; 14 | while (q--) { 15 | Point a, b, c, d; cin >> a >> b >> c >> d; 16 | Line l1(a, b), l2(c, d); 17 | 18 | if (areParallel(l1, l2)) cout << 2; 19 | else if (orthogonal(l1, l2)) cout << 1; 20 | else cout << 0; 21 | cout << endl; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_2_b_basic_segment_intersect.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | 6 | void solve() { 7 | int q; cin >> q; 8 | while (q--) { 9 | Point a, b; cin >> a >> b; 10 | Point c, d; cin >> c >> d; 11 | cout << (segmentIntersect(a, b, c, d) ? 1 : 0) << '\n'; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_2_c_basic_line_intersection.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_C" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | 6 | void solve() { 7 | int q; cin >> q; 8 | cout << (fixed) << setprecision(10); 9 | while (q--) { 10 | Point a, b; cin >> a >> b; 11 | Point c, d; cin >> c >> d; 12 | assert(segmentIntersect(a, b, c, d)); 13 | Line l1(a, b); 14 | Line l2(c, d); 15 | Point p; 16 | assert(areIntersect(l1, l2, p)); 17 | // Hack to fix exact judge 18 | if (std::abs(p.x) < 1e-11) p.x = 0.0; 19 | if (std::abs(p.y) < 1e-11) p.y = 0.0; 20 | cout << p << '\n'; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_2_d_basic_segment_distance.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | 6 | void solve() { 7 | int q; cin >> q; 8 | cout << (fixed) << setprecision(10); 9 | while (q--) { 10 | Point a, b; cin >> a >> b; 11 | Point c, d; cin >> c >> d; 12 | Point t; 13 | 14 | if (segmentIntersect(a, b, c, d)) cout << 0.0 << endl; 15 | else { 16 | cout << min({ 17 | distToLineSegment(a, c, d, t), 18 | distToLineSegment(b, c, d, t), 19 | distToLineSegment(c, a, b, t), 20 | distToLineSegment(d, a, b, t) 21 | }) << '\n'; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_3_a_polygon_area.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_A" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | #include "../polygon.h" 6 | 7 | void solve() { 8 | int n; cin >> n; 9 | Polygon P(n); 10 | for (auto& p : P) cin >> p; 11 | cout << (fixed) << setprecision(1) << area(P) << endl; 12 | } 13 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_3_b_polygon_is_convex.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_B" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | #include "../polygon.h" 6 | 7 | void solve() { 8 | int n; cin >> n; 9 | Polygon g(n); 10 | for (auto& p : g) cin >> p; 11 | cout << (is_convex(g) ? 1 : 0) << endl; 12 | } 13 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_3_c_polygon_in_polygon.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_C" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | #include "../polygon.h" 6 | 7 | void solve() { 8 | int n; cin >> n; 9 | Polygon g(n); 10 | for (auto& p : g) cin >> p; 11 | 12 | int q; cin >> q; 13 | while (q--) { 14 | Point p; cin >> p; 15 | auto res = in_polygon(g, p); 16 | cout << res << '\n'; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_4_a_polygon_convex_hull.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_A" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | #include "../polygon.h" 6 | 7 | void solve() { 8 | int n; cin >> n; 9 | Polygon g(n); 10 | for (auto& p : g) cin >> p; 11 | ConvexHull(g); 12 | int idx = 0; 13 | FOR(i,1,n-1) if (cmpy(g[i], g[idx])) idx = i; 14 | 15 | cout << g.size() << endl; 16 | REP(i,g.size()) cout << (fixed) << setprecision(0) << g[(idx + i) % g.size()] << '\n'; 17 | } 18 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_4_b_polygon_convex_diameter.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_B" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | #include "../polygon.h" 6 | 7 | #define ERROR 1e-6 8 | 9 | void solve() { 10 | int n; cin >> n; 11 | Polygon a(n); 12 | REP(i,n) cin >> a[i]; 13 | 14 | cout << (fixed) << setprecision(10) << convex_diameter(a).first << endl; 15 | } 16 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_4_c_polygon_convex_cut.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_C" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | #include "../polygon.h" 6 | 7 | #define ERROR 1e-6 8 | 9 | void solve() { 10 | int n; cin >> n; 11 | Polygon p(n); 12 | REP(i,n) cin >> p[i]; 13 | 14 | cout << (fixed) << setprecision(10); 15 | int q; cin >> q; 16 | while (q--) { 17 | Point a, b; cin >> a >> b; 18 | Line l(a, b); 19 | cout << area(polygon_cut(p, l)) << '\n'; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_5_a_closest_pair.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_5_A" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | #include "../closest_pair.h" 6 | 7 | #define ERROR 1e-6 8 | 9 | void solve() { 10 | cout << (fixed) << setprecision(10); 11 | int n; cin >> n; 12 | vector> a(n); 13 | for (auto& p : a) cin >> p; 14 | 15 | auto [dist, ps] = closest_pair(a); 16 | cout << dist << endl; 17 | } 18 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_7_a_cicle_tangents.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_A" 2 | 3 | // Given 2 circles, return how many common tangents 4 | 5 | #include "../../template.h" 6 | #include "../basic.h" 7 | #include "../circle.h" 8 | 9 | void solve() { 10 | Circle c1, c2; cin >> c1 >> c2; 11 | cout << tangents(c1, c2).size() << endl; 12 | } 13 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_7_d_circle_line_intersection.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_D" 2 | 3 | // Given circle and line. Print intersection points (there are always >= 1) 4 | 5 | #include "../../template.h" 6 | #include "../basic.h" 7 | #include "../circle.h" 8 | 9 | #define ERROR 1e-6 10 | 11 | void solve() { 12 | Circle c; cin >> c; 13 | int q; cin >> q; 14 | cout << (fixed) << setprecision(10); 15 | while (q--) { 16 | Point a, b; cin >> a >> b; 17 | Line l(a, b); 18 | auto ps = intersection(l, c); 19 | if (ps.size() == 1) ps.push_back(ps[0]); 20 | sort(ps.begin(), ps.end()); 21 | cout << ps[0] << ' ' << ps[1] << endl; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_7_e_circle_circle_intersection.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_E" 2 | 3 | // Given 2 intersecting circles, find intersection points 4 | 5 | #include "../../template.h" 6 | #include "../basic.h" 7 | #include "../circle.h" 8 | 9 | #define ERROR 1e-6 10 | 11 | void solve() { 12 | cout << (fixed) << setprecision(10); 13 | Circle c1, c2; 14 | cin >> c1 >> c2; 15 | auto ps = circleIntersect(c1, c2); 16 | assert(ps.size() > 0); 17 | if (ps.size() == 1) ps.push_back(ps[0]); 18 | sort(ps.begin(), ps.end()); 19 | 20 | cout << ps[0] << ' ' << ps[1] << endl; 21 | } 22 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_7_f_circle_tangent_points.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_F" 2 | 3 | // Given point p and circle c. p is outside c. Find all tangents and print tangent points on c. 4 | 5 | #include "../../template.h" 6 | #include "../basic.h" 7 | #include "../circle.h" 8 | 9 | #define ERROR 1e-6 10 | 11 | void solve() { 12 | cout << (fixed) << setprecision(10); 13 | Point p; 14 | Circle c; 15 | cin >> p >> c; 16 | auto ls = tangents(Circle(p, 0.0), c); 17 | vector ps; 18 | for (auto l : ls) { 19 | auto cur = intersection(l, c); 20 | assert(!cur.empty()); 21 | ps.insert(ps.end(), cur.begin(), cur.end()); 22 | } 23 | sort(ps.begin(), ps.end()); 24 | ps.erase(unique(ps.begin(), ps.end()), ps.end()); 25 | 26 | assert(ps.size() > 0); 27 | if (ps.size() == 1) ps.push_back(ps[0]); 28 | sort(ps.begin(), ps.end()); 29 | 30 | cout << ps[0] << endl << ps[1] << endl; 31 | } 32 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_7_g_circle_circle_tangent_points.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_G" 2 | 3 | // Given 2 circles. Find all common tangents, and print tangent points on c1 4 | 5 | #include "../../template.h" 6 | #include "../basic.h" 7 | #include "../circle.h" 8 | 9 | #define ERROR 1e-6 10 | 11 | void solve() { 12 | cout << (fixed) << setprecision(10); 13 | Circle c1, c2; cin >> c1 >> c2; 14 | auto ts = tangents(c1, c2); 15 | vector ps; 16 | 17 | for (auto t : ts) { 18 | auto cur = intersection(t, c1); 19 | assert(!cur.empty()); 20 | ps.insert(ps.end(), cur.begin(), cur.end()); 21 | } 22 | sort(ps.begin(), ps.end()); 23 | ps.erase(unique(ps.begin(), ps.end()), ps.end()); 24 | 25 | for (auto p : ps) cout << p << endl; 26 | } 27 | -------------------------------------------------------------------------------- /Geometry/tests/aizu_cgl_7_i_circle_common_area.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_I" 2 | 3 | // Find common area of 2 circles 4 | 5 | #include "../../template.h" 6 | #include "../basic.h" 7 | #include "../circle.h" 8 | 9 | #define ERROR 1e-6 10 | 11 | void solve() { 12 | cout << (fixed) << setprecision(10); 13 | Circle c1, c2; cin >> c1 >> c2; 14 | cout << commonCircleArea(c1, c2) << endl; 15 | } 16 | -------------------------------------------------------------------------------- /Geometry/tests/polygon_in_convex.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0412" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | #include "../polygon.h" 6 | 7 | void solve() { 8 | int n; cin >> n; 9 | Polygon g(n); 10 | for (auto& p : g) cin >> p; 11 | 12 | int q; cin >> q; 13 | while (q--) { 14 | Point p; cin >> p; 15 | p = p - (p / 10000.0); 16 | cout << (in_convex(g, p) ? 1 : 0) << '\n'; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Geometry/tests/z_basic_ccw.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | 6 | using Pint = P; 7 | void solve() { 8 | Pint a, b; cin >> a >> b; 9 | int q; cin >> q; 10 | while (q--) { 11 | Pint c; cin >> c; 12 | auto t = ccw(a, b, c); 13 | if (t == 0) { 14 | if (onSegment(a, b, c)) cout << "ON_SEGMENT\n"; 15 | else if (onSegment(c, b, a)) cout << "ONLINE_BACK\n"; 16 | else cout << "ONLINE_FRONT\n"; 17 | } else if (t < 0) cout << "CLOCKWISE\n"; 18 | else cout << "COUNTER_CLOCKWISE\n"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Geometry/tests/z_basic_segment_intersect.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | 6 | void solve() { 7 | int q; cin >> q; 8 | while (q--) { 9 | P a, b; cin >> a >> b; 10 | P c, d; cin >> c >> d; 11 | cout << (segmentIntersect(a, b, c, d) ? 1 : 0) << '\n'; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Geometry/tests/z_polygon_area.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_A" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | #include "../polygon.h" 6 | 7 | void solve() { 8 | int n; cin >> n; 9 | vector> P(n); 10 | for (auto& p : P) cin >> p; 11 | long long res = signed_area2(P); 12 | cout << (fixed) << setprecision(1) << std::abs(res / 2.0) << endl; 13 | } 14 | -------------------------------------------------------------------------------- /Geometry/tests/z_polygon_convexhull.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_A" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | #include "../polygon.h" 6 | 7 | void solve() { 8 | int n; cin >> n; 9 | vector> g(n); 10 | for (auto& p : g) cin >> p; 11 | ConvexHull(g); 12 | int idx = 0; 13 | FOR(i,1,n-1) if (cmpy(g[i], g[idx])) idx = i; 14 | 15 | cout << g.size() << endl; 16 | REP(i,g.size()) cout << (fixed) << setprecision(0) << g[(idx + i) % g.size()] << endl; 17 | } 18 | -------------------------------------------------------------------------------- /Geometry/tests/z_polygon_is_convex.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_B" 2 | 3 | #include "../../template.h" 4 | #include "../basic.h" 5 | #include "../polygon.h" 6 | 7 | void solve() { 8 | int n; cin >> n; 9 | vector> g(n); 10 | for (auto& p : g) cin >> p; 11 | cout << (is_convex(g) ? 1 : 0) << endl; 12 | } 13 | -------------------------------------------------------------------------------- /Graph/DfsTree/.gitignore: -------------------------------------------------------------------------------- 1 | StronglyConnected 2 | BridgeArticulation 3 | -------------------------------------------------------------------------------- /Graph/Matching/.gitignore: -------------------------------------------------------------------------------- 1 | GeneralMatching 2 | HungarianAssignment 3 | SPOJ_MATCH2 4 | SPOJ_QBFLOWER 5 | -------------------------------------------------------------------------------- /Graph/Matching/StableMarriage.h: -------------------------------------------------------------------------------- 1 | /* Numbered from 0 2 | * For man i, L[i] = list of women in order of decreasing preference 3 | * For women j, R[j][i] = index of man i in j-th women's list of preference 4 | * OUTPUTS: 5 | * - L2R[]: the mate of man i (always between 0 and n-1) 6 | * - R2L[]: the mate of woman j (or -1 if single) 7 | * COMPLEXITY: M^2 8 | */ 9 | 10 | #define MAXM 1024 11 | #define MAXW 1024 12 | int m; 13 | int L[MAXM][MAXW], R[MAXW][MAXM]; 14 | int L2R[MAXM], R2L[MAXW]; 15 | int p[MAXM]; 16 | void stableMarriage(){ 17 | static int p[128]; 18 | memset(R2L, -1, sizeof R2L); 19 | memset(p, 0, sizeof p); 20 | // Each man proposes... 21 | for(int i = 0; i < m; i++) { 22 | int man = i; 23 | while (man >= 0) { // propose until success 24 | int wom; 25 | while (1) { 26 | wom = L[man][p[man]++]; 27 | if (R2L[wom] < 0 || R[wom][man] > R[wom][R2L[wom]]) break; 28 | } 29 | int hubby = R2L[wom]; 30 | R2L[L2R[man] = wom] = man; 31 | man = hubby; // remarry the dumped guy 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Graph/MaxFlow/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore executable files 2 | VOJ_NKFLOW 3 | VOJ_FFLOW 4 | VOJ_MINCOST 5 | VOJ_MCQUERY 6 | SPOJ_FASTFLOW 7 | -------------------------------------------------------------------------------- /Graph/MaxFlow/MaxClosure.txt: -------------------------------------------------------------------------------- 1 | Problem: Given directed G=(V,E) and cost function f: V --> R. Find max (or min) weight closure. (Closure: set of vertices with no outgoing edges) 2 | Max closure <--> Min closure: compliment 3 | Max closure <--> Min cut in H, where H is constructed as follow: 4 | - Add source s, sink t 5 | - if f(v) > 0 --> add edge (s, v) with capacity = f(v) 6 | - if f(v) < 0 --> add edge (v, t) with capacity = -f(v) 7 | - All edges in G have infinite capacity in H 8 | 9 | Vertices in same side as s forms a closure. Weight(cut) = sum(f(v) where f(v) > 0) - weight(closure) --> cut is minimum when closure is maximum 10 | 11 | Wiki: https://en.wikipedia.org/wiki/Closure_problem 12 | -------------------------------------------------------------------------------- /Graph/MaxFlow/MinimumCut.h: -------------------------------------------------------------------------------- 1 | // Minimum cut between every pair of vertices (Stoer Wagner) 2 | pair> GetMinCut(const vector> &weights) { 3 | int N = weights.size(); 4 | vector used(N), cut, best_cut; 5 | int best_weight = -1; 6 | 7 | for (int phase = N-1; phase >= 0; phase--) { 8 | vector w = weights[0]; 9 | vector added = used; 10 | int prev, last = 0; 11 | for (int i = 0; i < phase; i++) { 12 | prev = last; 13 | last = -1; 14 | for (int j = 1; j < N; j++) 15 | if (!added[j] && (last == -1 || w[j] > w[last])) last = j; 16 | if (i == phase-1) { 17 | for (int j = 0; j < N; j++) weights[prev][j] += weights[last][j]; 18 | for (int j = 0; j < N; j++) weights[j][prev] = weights[prev][j]; 19 | used[last] = true; 20 | cut.push_back(last); 21 | if (best_weight == -1 || w[last] < best_weight) { 22 | best_cut = cut; 23 | best_weight = w[last]; 24 | } 25 | } 26 | else { 27 | for (int j = 0; j < N; j++) 28 | w[j] += weights[last][j]; 29 | added[last] = true; 30 | } 31 | } 32 | } 33 | return make_pair(best_weight, best_cut); 34 | } 35 | -------------------------------------------------------------------------------- /Graph/MaxFlow/upper_lower.txt: -------------------------------------------------------------------------------- 1 | // Tested: 2 | // - http://codeforces.com/gym/100199/submission/12608232 3 | // - SGU 176 4 | 5 | Feasible flow in network with upper + lower constraint, no source, no sink: 6 | - For each edge in original flow: 7 | - Add edge with cap' = upper bound - lower bound. 8 | - Add source s, sink t. 9 | - Let M[v] = (sum of lowerbounds of ingoing edges to v) - (sum of lower bounds of outgoing edges from v). 10 | - For all v, if M[v] > 0, add (s, v, M), else add (v, t, -M). 11 | - If all outgoing edges from S are full --> feasible flow exists, it is flow + lower bounds. 12 | 13 | Feasible flow in network with upper + lower constraint, with source & sink: 14 | - Add edge (t, s) with capacity [0, INF]. 15 | - Check feasible in network without source & sink. 16 | 17 | Max flow with both upper + lower constraints, source s, sink t: add edge (t, s, +INF). 18 | - Binary search lower bound, check whether feasible flow exists WITHOUT source / sink 19 | -------------------------------------------------------------------------------- /Graph/bipartite_coloring.h: -------------------------------------------------------------------------------- 1 | // Bipartite coloring (color graph with 2 colors) 2 | // Graph is 0-based 3 | // Returns: 4 | // - can color? 5 | // - color, 1-based 6 | // 7 | // Tested: 8 | // - https://cses.fi/problemset/task/1668 9 | pair> bipartite_coloring(const vector>& g) { 10 | int n = g.size(); 11 | vector color(n, -1); 12 | 13 | std::function dfs = [&] (int u) { 14 | for (int v : g[u]) { 15 | if (color[v] < 0) { 16 | color[v] = 3 - color[u]; 17 | dfs(v); 18 | } else if (color[u] == color[v]) { 19 | throw 1; 20 | } 21 | } 22 | }; 23 | 24 | try { 25 | for (int i = 0; i < n; i++) { 26 | if (color[i] < 0) { 27 | color[i] = 1; 28 | dfs(i); 29 | } 30 | } 31 | } catch (...) { 32 | return {false, {}}; 33 | } 34 | 35 | return {true, color}; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Graph/find_triangles.h: -------------------------------------------------------------------------------- 1 | // Find all cycles of length 3 (a.k.a. triangles) 2 | // Complexity: O(N + M*sqrt(M)) 3 | // 4 | // Index from 0 5 | // 6 | // Tested: 7 | // - https://judge.yosupo.jp/problem/enumerate_triangles 8 | vector< tuple > find_all_triangles( 9 | int n, 10 | vector> edges) { 11 | // Remove duplicated edges 12 | sort(edges.begin(), edges.end()); 13 | edges.erase(unique(edges.begin(), edges.end()), edges.end()); 14 | 15 | // Compute degs 16 | vector deg(n, 0); 17 | for (const auto& [u, v] : edges) { 18 | if (u == v) continue; 19 | ++deg[u], ++deg[v]; 20 | } 21 | 22 | // Add edge (u, v) where u is 'lower' than v 23 | vector> adj(n); 24 | for (auto [u, v] : edges) { 25 | if (u == v) continue; 26 | if (deg[u] > deg[v] || (deg[u] == deg[v] && u > v)) swap(u, v); 27 | adj[u].push_back(v); 28 | } 29 | 30 | // Find all triplets. 31 | // If it's too slow, remove vector res and compute answer directly 32 | vector> res; 33 | vector good(n, false); 34 | for (int i = 0; i < n; i++) { 35 | for (auto j : adj[i]) good[j] = true; 36 | for (auto j : adj[i]) { 37 | for (auto k : adj[j]) { 38 | if (good[k]) { 39 | res.emplace_back(i, j, k); 40 | } 41 | } 42 | } 43 | for (auto j : adj[i]) good[j] = false; 44 | } 45 | return res; 46 | } 47 | -------------------------------------------------------------------------------- /Graph/floyd.h: -------------------------------------------------------------------------------- 1 | // Tested: 2 | // - https://cses.fi/problemset/task/1672/ 3 | // - (trace) https://oj.vnoi.info/problem/floyd 4 | using ll = long long; 5 | const ll INF = 4e18; 6 | struct Floyd { 7 | Floyd(int _n, const std::vector> _c) : n(_n), c(_c), trace(n) { 8 | for (int i = 0; i < n; i++) { 9 | trace[i] = std::vector (n, -1); 10 | for (int j = 0; j < n; j++) { 11 | if (c[i][j] == INF) trace[i][j] = -1; 12 | else trace[i][j] = i; 13 | } 14 | } 15 | 16 | for (int k = 0; k < n; k++) { 17 | for (int i = 0; i < n; i++) { 18 | for (int j = 0; j < n; j++) { 19 | if (c[i][k] != INF && c[k][j] != INF && c[i][j] > c[i][k] + c[k][j]) { 20 | c[i][j] = c[i][k] + c[k][j]; 21 | trace[i][j] = trace[k][j]; 22 | } 23 | } 24 | } 25 | } 26 | } 27 | 28 | // Return {distance, path} 29 | // If no path -> returns {-1, {}} 30 | std::pair> get_path(int start, int target) { 31 | if (trace[start][target] == -1) return {-1, {}}; 32 | 33 | std::vector path; 34 | for (int u = target; u != start; u = trace[start][u]) { 35 | path.push_back(u); 36 | } 37 | path.push_back(start); 38 | reverse(path.begin(), path.end()); 39 | return {c[start][target], path}; 40 | } 41 | 42 | int n; 43 | std::vector> c; 44 | std::vector> trace; 45 | }; 46 | 47 | -------------------------------------------------------------------------------- /Graph/ford_bellman.h: -------------------------------------------------------------------------------- 1 | // Ford Bellman, O(N*M) 2 | // Tested: 3 | // - https://cses.fi/problemset/task/1673 4 | using ll = long long; 5 | const ll INF = 4e18; 6 | struct Edge { int u, v; ll cost; }; // one-direction 7 | 8 | // Returns {is distance to target bounded?, shortest distance from start -> target} 9 | std::pair ford_bellman(int n, int start, int target, const vector& edges) { 10 | int m = edges.size(); 11 | std::vector f(n, INF); 12 | f[start] = 0; 13 | 14 | // Init f 15 | for (int turn = 0; turn < m; turn++) { 16 | for (auto [u, v, cost] : edges) { 17 | if (f[u] != INF && f[v] > f[u] + cost) { 18 | f[v] = f[u] + cost; 19 | } 20 | } 21 | } 22 | 23 | // Find all unbounded vertices 24 | auto cur_f = f; 25 | for (int turn = 0; turn < m; turn++) { 26 | for (auto [u, v, cost] : edges) { 27 | if (f[u] != INF && f[v] > f[u] + cost) { 28 | f[v] = f[u] + cost; 29 | } 30 | } 31 | } 32 | 33 | // Set all unbounded vertices to -INF 34 | for (int i = 0; i < n; i++) { 35 | if (f[i] != cur_f[i]) { 36 | f[i] = -INF; 37 | } 38 | } 39 | 40 | // Re-update all f 41 | for (int turn = 0; turn < m; turn++) { 42 | for (auto [u, v, cost] : edges) { 43 | if (f[u] != INF && f[v] > f[u] + cost) { 44 | f[v] = f[u] + cost; 45 | } 46 | } 47 | } 48 | return {f[target] == cur_f[target], f[target]}; 49 | } 50 | -------------------------------------------------------------------------------- /Graph/mst.h: -------------------------------------------------------------------------------- 1 | // MST. 0-based index 2 | // 3 | // Returns: 4 | // {mst cost, edges in mst} 5 | // 6 | // If graph is not connected, returns forest (number of edges will be < n-1) 7 | 8 | #include "../DataStructure/DSU/DisjointSet.h" 9 | 10 | // MST {{{ 11 | using ll = long long; 12 | template 13 | std::pair> mst( 14 | int n, 15 | std::vector edges) { 16 | std::sort(edges.begin(), edges.end()); 17 | 18 | DSU dsu(n + 1); // tolerate 1-based index 19 | ll total = 0; 20 | vector tree; 21 | for (const auto& e : edges) { 22 | if (dsu.merge(e.u, e.v)) { 23 | total += e.c; 24 | tree.push_back(e); 25 | } 26 | } 27 | return {total, tree}; 28 | } 29 | struct Edge { 30 | int u, v; 31 | ll c; 32 | }; 33 | bool operator < (const Edge& a, const Edge& b) { 34 | return a.c < b.c; 35 | } 36 | ostream& operator << (ostream& out, const Edge& e) { 37 | out << e.u << " - " << e.v << " [" << e.c << ']'; 38 | return out; 39 | } 40 | // }}} 41 | -------------------------------------------------------------------------------- /Graph/tests/aizu_alds1_11_c_bfs.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_11_C" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../bfs.h" 7 | 8 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 9 | 10 | int main() { 11 | ios::sync_with_stdio(0); cin.tie(0); 12 | int n; cin >> n; 13 | Graph g(n); 14 | 15 | REP(i,n) { 16 | int u, k; cin >> u >> k; 17 | --u; 18 | while (k--) { 19 | int v; cin >> v; 20 | --v; 21 | g.add_edge(u, v); 22 | } 23 | } 24 | auto dist = g.bfs(0); 25 | REP(i,n) { 26 | cout << (i+1) << ' ' << dist[i] << '\n'; 27 | } 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /Graph/tests/aizu_grl_1_a_dijkstra_aizu.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_A" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../dijkstra.h" 7 | 8 | int main() { 9 | ios::sync_with_stdio(0); cin.tie(0); 10 | int n, m, start; cin >> n >> m >> start; 11 | vector< vector> > g(n); 12 | while (m--) { 13 | int u, v, c; cin >> u >> v >> c; 14 | g[u].push_back({v, c}); 15 | } 16 | auto [dist, trace] = dijkstra(g, start); 17 | for (auto d : dist) { 18 | if (d == INF) cout << "INF\n"; 19 | else cout << d << '\n'; 20 | } 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Graph/tests/aizu_grl_1_c_floyd.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_C" 2 | 3 | #include "../../template.h" 4 | #include "../floyd.h" 5 | 6 | void solve() { 7 | int n, m; cin >> n >> m; 8 | vector> c(n, vector (n, INF)); 9 | for (int i = 0; i < n; i++) c[i][i] = 0; 10 | 11 | while (m--) { 12 | int u, v; ll cost; cin >> u >> v >> cost; 13 | c[u][v] = min(c[u][v], cost); 14 | } 15 | 16 | Floyd f(n, c); 17 | for (int i = 0; i < n; i++) { 18 | if (f.c[i][i] < 0) { 19 | cout << "NEGATIVE CYCLE" << endl; 20 | return; 21 | } 22 | } 23 | for (int i = 0; i < n; i++) { 24 | for (int j = 0; j < n; j++) { 25 | if (f.c[i][j] == INF) cout << "INF"; 26 | else cout << f.c[i][j]; 27 | cout << (j == n-1 ? '\n' : ' '); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Graph/tests/aizu_grl_2_a_mst.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_2_A" 2 | 3 | #include "../../template.h" 4 | #include "../mst.h" 5 | 6 | void solve() { 7 | int n, m; cin >> n >> m; 8 | vector edges(m); 9 | for (auto& [u, v, c] : edges) cin >> u >> v >> c; 10 | 11 | cout << mst(n, edges).first << endl; 12 | } 13 | -------------------------------------------------------------------------------- /Graph/tests/aizu_grl_2_b_directed_mst.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_2_B" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../DirectedMST.h" 7 | 8 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 9 | 10 | int32_t main() { 11 | ios::sync_with_stdio(0); cin.tie(0); 12 | int n, m, root; cin >> n >> m >> root; 13 | vector edges(m); 14 | for (auto& e : edges) { 15 | cin >> e.u >> e.v >> e.cost; 16 | } 17 | auto [total, par] = directed_mst(n, root, edges); 18 | cout << total << endl; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /Graph/tests/aizu_grl_3_a_articulation_points.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_3_A" 2 | 3 | #include "../../template.h" 4 | #include "../DfsTree/BridgeArticulation.h" 5 | 6 | void solve() { 7 | int n, m; cin >> n >> m; 8 | vector> g(n); 9 | REP(i,m) { 10 | int u, v; cin >> u >> v; 11 | g[u].push_back(v); 12 | g[v].push_back(u); 13 | } 14 | 15 | UndirectedDfs tree(g); 16 | auto res = tree.articulation_points; 17 | sort(res.begin(), res.end()); 18 | for (int r : res) cout << r << '\n'; 19 | } 20 | -------------------------------------------------------------------------------- /Graph/tests/aizu_grl_3_b_bridge.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_3_B" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../DfsTree/BridgeArticulation.h" 7 | 8 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 9 | 10 | int main() { 11 | ios::sync_with_stdio(0); cin.tie(0); 12 | int n, m; cin >> n >> m; 13 | vector> g(n); 14 | REP(i,m) { 15 | int u, v; cin >> u >> v; 16 | g[u].push_back(v); 17 | g[v].push_back(u); 18 | } 19 | 20 | UndirectedDfs tree(g); 21 | auto bridges = tree.bridges; 22 | 23 | for (auto& [u, v] : bridges) { 24 | if (u > v) swap(u, v); 25 | } 26 | sort(bridges.begin(), bridges.end()); 27 | 28 | for (auto [u, v] : bridges) { 29 | cout << u << ' ' << v << endl; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Graph/tests/aizu_grl_3_c_strongly_connected.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_3_C" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../DfsTree/StronglyConnected.h" 7 | 8 | int main() { 9 | ios::sync_with_stdio(0); cin.tie(0); 10 | int n, m; cin >> n >> m; 11 | vector> g(n); 12 | while (m--) { 13 | int u, v; cin >> u >> v; 14 | g[u].push_back(v); 15 | } 16 | DirectedDfs tree(g); 17 | 18 | int q; cin >> q; 19 | while (q--) { 20 | int u, v; cin >> u >> v; 21 | cout << (tree.comp_ids[u] == tree.comp_ids[v]) << '\n'; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Graph/tests/aizu_grl_4_a_strongly_connected_cycle_check.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_4_A" 2 | 3 | #include "../../template.h" 4 | #include "../DfsTree/StronglyConnected.h" 5 | 6 | void solve() { 7 | int n, m; cin >> n >> m; 8 | vector> g(n); 9 | while (m--) { 10 | int u, v; cin >> u >> v; 11 | g[u].push_back(v); 12 | } 13 | DirectedDfs tree(g); 14 | for (auto comp : tree.scc) { 15 | if (comp.size() > 1) { 16 | cout << 1 << endl; 17 | return; 18 | } 19 | } 20 | cout << 0 << endl; 21 | } 22 | -------------------------------------------------------------------------------- /Graph/tests/aizu_grl_5_a_tree_diameter.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_A" 2 | 3 | #include "../../template.h" 4 | #include "../tree_diameter.h" 5 | 6 | void solve() { 7 | int n; cin >> n; 8 | vector>> g(n); 9 | REP(i,n-1) { 10 | int u, v, cost; cin >> u >> v >> cost; 11 | g[u].emplace_back(v, cost); 12 | g[v].emplace_back(u, cost); 13 | } 14 | 15 | auto [length, path] = tree_diameter(g); 16 | cout << length << endl; 17 | } 18 | -------------------------------------------------------------------------------- /Graph/tests/aizu_grl_6_a_maxflow_dinic.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_A" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../MaxFlow/MaxFlowDinic.h" 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(0); cin.tie(0); 10 | int n, m; cin >> n >> m; 11 | 12 | MaxFlow flow(n); 13 | while (m--) { 14 | int u, v, c; cin >> u >> v >> c; 15 | flow.addEdge(u, v, c); 16 | } 17 | cout << flow.getMaxFlow(0, n-1) << endl; 18 | } 19 | -------------------------------------------------------------------------------- /Graph/tests/aizu_grl_6_a_maxflow_hlpp.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_A" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../MaxFlow/MaxFlowHLPP.h" 7 | 8 | MaxFlow<111, int> flow; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(0); cin.tie(0); 12 | int n, m; cin >> n >> m; 13 | 14 | while (m--) { 15 | int u, v, c; cin >> u >> v >> c; 16 | flow.addEdge(u, v, c); 17 | } 18 | cout << flow.getMaxFlow(0, n-1) << endl; 19 | } 20 | -------------------------------------------------------------------------------- /Graph/tests/aizu_grl_6_a_maxflow_pr.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_A" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../MaxFlow/MaxFlowPR.h" 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(0); cin.tie(0); 10 | int n, m; cin >> n >> m; 11 | 12 | MaxFlow flow(n); 13 | while (m--) { 14 | int u, v, c; cin >> u >> v >> c; 15 | flow.addEdge(u, v, c); 16 | } 17 | cout << flow.getMaxFlow(0, n-1) << endl; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /Graph/tests/aizu_grl_6_b_mincost_maxflow.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_B" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../MaxFlow/MinCostMaxFlowPR.h" 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(0); cin.tie(0); 10 | int n, m, fl; cin >> n >> m >> fl; 11 | 12 | MinCostFlow flow(n+1, 0, n); 13 | flow.addEdge(n-1, n, fl, 0); 14 | while (m--) { 15 | int u, v, f, c; cin >> u >> v >> f >> c; 16 | flow.addEdge(u, v, f, c); 17 | } 18 | auto [f, c] = flow.minCostMaxFlow(); 19 | if (f < fl) { 20 | cout << -1 << endl; 21 | } else { 22 | cout << c << endl; 23 | } 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Graph/tests/aizu_grl_6_b_mincost_maxflow_spfa.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_B" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../MaxFlow/MinCostMaxFlowSPFA.h" 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(0); cin.tie(0); 10 | int n, m, fl; cin >> n >> m >> fl; 11 | 12 | MinCostFlow flow(n+1); 13 | flow.addEdge(n-1, n, fl, 0); 14 | while (m--) { 15 | int u, v, f, c; cin >> u >> v >> f >> c; 16 | flow.addEdge(u, v, f, c); 17 | } 18 | auto [f, c] = flow.minCostFlow(0, n); 19 | if (f < fl) { 20 | cout << -1 << endl; 21 | } else { 22 | cout << c << endl; 23 | } 24 | return 0; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /Graph/tests/aizu_grl_7_a_matching_bipartite.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_7_A" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../Matching/BipartiteMatching.h" 7 | 8 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 9 | mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); 10 | 11 | int32_t main() { 12 | ios::sync_with_stdio(0); cin.tie(0); 13 | int left, right, m; cin >> left >> right >> m; 14 | Matching mat(max(left, right)); 15 | while (m--) { 16 | int u, v; cin >> u >> v; 17 | mat.addEdge(u, v); 18 | } 19 | 20 | REP(i,left) { 21 | shuffle(mat.ke[i].begin(), mat.ke[i].end(), rng); 22 | } 23 | 24 | cout << mat.match() << '\n'; 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Graph/tests/bipartite_coloring.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/bipartite_edge_coloring" 2 | 3 | #include 4 | using namespace std; 5 | 6 | const int N = 1e5 + 11; 7 | #include "../bipartite_edge_coloring.h" 8 | 9 | int32_t main() { 10 | ios_base::sync_with_stdio(0); cin.tie(0); 11 | int l, r, m; cin >> l >> r >> m; 12 | vector ed(m); 13 | for (auto &x: ed) { 14 | cin >> x[0] >> x[1]; 15 | } 16 | EdgeColoring E; 17 | vector ans; 18 | int cnt = E.solve(ed, ans); 19 | cout << cnt << '\n'; 20 | for (auto &x: ans) cout << x - 1 << endl; 21 | cout << endl; 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Graph/tests/clique_maxindependentset.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/maximum_independent_set" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../MaxClique.h" 7 | 8 | bool edge[44][44]; 9 | 10 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 11 | 12 | int32_t main() { 13 | ios::sync_with_stdio(0); cin.tie(0); 14 | int n, m; cin >> n >> m; 15 | 16 | REP(i,m) { 17 | int u, v; cin >> u >> v; 18 | edge[u][v] = edge[v][u] = 1; 19 | } 20 | 21 | MaxClique g(n); 22 | REP(i,n) REP(j,n) if (!edge[i][j] && i != j) { 23 | g.addEdge(i, j); 24 | } 25 | 26 | auto res = g.solve(); 27 | cout << res.size() << endl; 28 | for (int x : res) { 29 | cout << x << ' '; 30 | } 31 | cout << endl; 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Graph/tests/dijkstra.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/shortest_path" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../dijkstra.h" 7 | 8 | #define SZ(x) ((int)(x).size()) 9 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 10 | 11 | int32_t main() { 12 | ios::sync_with_stdio(0); cin.tie(0); 13 | int n, m, s, t; cin >> n >> m >> s >> t; 14 | 15 | // read edges 16 | vector>> g(n); 17 | while (m--) { 18 | int u, v, c; cin >> u >> v >> c; 19 | g[u].push_back({v, c}); 20 | } 21 | 22 | // output 23 | auto [dist, path] = dijkstra(g, s, t); 24 | if (dist == INF) { 25 | cout << -1 << endl; 26 | return 0; 27 | } 28 | 29 | cout << dist << ' ' << SZ(path) - 1 << '\n'; 30 | REP(i,SZ(path)-1) { 31 | cout << path[i] << ' ' << path[i+1] << '\n'; 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /Graph/tests/directed_mst.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/directedmst" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../DirectedMST.h" 7 | 8 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 9 | 10 | int32_t main() { 11 | ios::sync_with_stdio(0); cin.tie(0); 12 | int n, m, root; cin >> n >> m >> root; 13 | vector edges(m); 14 | for (auto& e : edges) { 15 | cin >> e.u >> e.v >> e.cost; 16 | } 17 | auto [total, par] = directed_mst(n, root, edges); 18 | cout << total << endl; 19 | REP(i,n) cout << (i == root ? root : par[i]) << ' '; 20 | cout << endl; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Graph/tests/matching_bipartite.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/bipartitematching" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../Matching/BipartiteMatching.h" 7 | 8 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 9 | mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); 10 | 11 | int32_t main() { 12 | ios::sync_with_stdio(0); cin.tie(0); 13 | int left, right, m; cin >> left >> right >> m; 14 | Matching mat(max(left, right)); 15 | while (m--) { 16 | int u, v; cin >> u >> v; 17 | mat.addEdge(u, v); 18 | } 19 | 20 | REP(i,left) { 21 | shuffle(mat.ke[i].begin(), mat.ke[i].end(), rng); 22 | } 23 | 24 | cout << mat.match() << '\n'; 25 | REP(i,left) { 26 | if (mat.matchL[i] >= 0) { 27 | cout << i << ' ' << mat.matchL[i] << '\n'; 28 | } 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Graph/tests/matching_bipartite_weighted.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/assignment" 2 | 3 | #include 4 | using namespace std; 5 | 6 | const int MN = 511; 7 | const long long inf = 1000111000111LL; 8 | int N; 9 | 10 | #define FOR(i, a, b) for (int i = (a), _##i = (b); i <= _##i; ++i) 11 | #include "../Matching/HungarianLMH.h" 12 | 13 | int32_t main() { 14 | ios::sync_with_stdio(0); cin.tie(0); 15 | cin >> N; 16 | FOR(i,1,N) FOR(j,1,N) cin >> c[i][j]; 17 | cout << mincost() << '\n'; 18 | FOR(i,1,N) { 19 | cout << mx[i] - 1 << ' '; 20 | } 21 | cout << '\n'; 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Graph/tests/matching_bipartite_weighted_2.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/assignment" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../Matching/Hungarian_short.h" 7 | 8 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 9 | long long c[N][N]; 10 | 11 | int32_t main() { 12 | ios::sync_with_stdio(0); cin.tie(0); 13 | int n; cin >> n; 14 | REP(i,n) REP(j,n) cin >> c[i][j]; 15 | 16 | auto [cost, matchL] = Hungarian(n, n, c); 17 | cout << cost << endl; 18 | for (int m : matchL) cout << m << ' '; 19 | cout << endl; 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Graph/tests/matching_general.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/general_matching" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../Matching/GeneralMatching.h" 7 | 8 | int32_t main() { 9 | ios::sync_with_stdio(0); cin.tie(0); 10 | int n, m; cin >> n >> m; 11 | GeneralMatching match(n); 12 | while (m--) { 13 | int a, b; cin >> a >> b; 14 | match.add_edge(a, b); 15 | } 16 | cout << match.get_match() << '\n'; 17 | for (int i = 0; i < n; i++) { 18 | if (match.match[i] != -1 && match.match[i] > i) { 19 | cout << i << ' ' << match.match[i] << '\n'; 20 | } 21 | } 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Graph/tests/strongly_connected.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/scc" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../DfsTree/StronglyConnected.h" 7 | 8 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 9 | #define SZ(x) ((int)(x).size()) 10 | 11 | int32_t main() { 12 | ios::sync_with_stdio(0); cin.tie(0); 13 | int n, m; cin >> n >> m; 14 | vector> g(n); 15 | REP(i,m) { 16 | int u, v; cin >> u >> v; 17 | g[u].push_back(v); 18 | } 19 | 20 | DirectedDfs tree(g); 21 | 22 | reverse(tree.scc.begin(), tree.scc.end()); 23 | cout << SZ(tree.scc) << endl; 24 | for (auto comp : tree.scc) { 25 | cout << comp.size(); 26 | for (int x : comp) cout << ' ' << x; 27 | cout << '\n'; 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Graph/tests/tree_diameter.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/tree_diameter" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../tree_diameter.h" 7 | 8 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 9 | #define SZ(x) ((int)(x).size()) 10 | 11 | int32_t main() { 12 | ios::sync_with_stdio(0); cin.tie(0); 13 | int n; cin >> n; 14 | vector>> g(n); 15 | REP(i,n-1) { 16 | int u, v, cost; cin >> u >> v >> cost; 17 | g[u].emplace_back(v, cost); 18 | g[v].emplace_back(u, cost); 19 | } 20 | 21 | auto [length, path] = tree_diameter(g); 22 | cout << length << ' ' << SZ(path) << endl; 23 | for (int x : path) cout << x << ' '; 24 | cout << endl; 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Graph/tests/triangles.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/enumerate_triangles" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../find_triangles.h" 7 | 8 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 9 | 10 | int32_t main() { 11 | ios::sync_with_stdio(0); cin.tie(0); 12 | int n, m; cin >> n >> m; 13 | vector xs(n); 14 | REP(i,n) cin >> xs[i]; 15 | 16 | vector> edges(m); 17 | for (auto& [u, v] : edges) { 18 | cin >> u >> v; 19 | } 20 | 21 | auto res = find_all_triangles(n, edges); 22 | long long sum = 0; 23 | const int MOD = 998244353; 24 | for (auto [i, j, k] : res) { 25 | sum = (sum + xs[i] * xs[j] % MOD * xs[k]) % MOD; 26 | } 27 | cout << sum << endl; 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /Graph/tests/two_sat.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/two_sat" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../2sat.h" 7 | 8 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 9 | 10 | int32_t main() { 11 | ios::sync_with_stdio(0); cin.tie(0); 12 | string wtf; cin >> wtf >> wtf; 13 | int n, m; cin >> n >> m; 14 | TwoSatSolver solver(n); 15 | while (m--) { 16 | int x, y; cin >> x >> y >> wtf; 17 | solver.x_or_y_constraint(x > 0, std::abs(x) - 1, y > 0, std::abs(y) - 1); 18 | } 19 | auto [has_solution, sol] = solver.solve(); 20 | if (has_solution) { 21 | cout << "s SATISFIABLE" << endl; 22 | cout << "v "; 23 | REP(i,n) { 24 | if (sol[i]) cout << i+1; 25 | else cout << "-" << (i+1); 26 | cout << ' '; 27 | } 28 | cout << 0 << endl; 29 | } else { 30 | cout << "s UNSATISFIABLE" << endl; 31 | } 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Graph/tests/yosupo_mst.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/minimum_spanning_tree" 2 | 3 | #include "../../template.h" 4 | #include "../mst.h" 5 | 6 | struct E : Edge { 7 | int id; 8 | }; 9 | 10 | void solve() { 11 | int n, m; cin >> n >> m; 12 | vector edges(m); 13 | REP(i,m) { 14 | auto& e = edges[i]; 15 | cin >> e.u >> e.v >> e.c; 16 | e.id = i; 17 | } 18 | auto g = mst(n, edges); 19 | cout << g.first << '\n'; 20 | for (auto& e : g.second) cout << e.id << ' '; 21 | cout << '\n'; 22 | } 23 | -------------------------------------------------------------------------------- /Graph/topo_sort.h: -------------------------------------------------------------------------------- 1 | // Topo sort 2 | // returns: 3 | // 4 | // Notes: 5 | // - To find lexicographically min -> change queue qu to set 6 | // (see https://www.spoj.com/problems/TOPOSORT/) 7 | // 8 | // Tested: 9 | // - https://cses.fi/problemset/task/1679/ 10 | // - https://cses.fi/problemset/task/1757/ 11 | std::pair> topo_sort(const std::vector>& g) { 12 | int n = g.size(); 13 | // init in_deg 14 | std::vector in_deg(n, 0); 15 | for (int u = 0; u < n; u++) { 16 | for (int v : g[u]) { 17 | in_deg[v]++; 18 | } 19 | } 20 | 21 | // find topo order 22 | std::vector res; 23 | std::queue qu; 24 | for (int u = 0; u < n; u++) { 25 | if (in_deg[u] == 0) { 26 | qu.push(u); 27 | } 28 | } 29 | 30 | while (!qu.empty()) { 31 | int u = qu.front(); qu.pop(); 32 | res.push_back(u); 33 | for (int v : g[u]) { 34 | in_deg[v]--; 35 | if (in_deg[v] == 0) { 36 | qu.push(v); 37 | } 38 | } 39 | } 40 | 41 | if ((int) res.size() < n) { 42 | return {false, {}}; 43 | } 44 | return {true, res}; 45 | } 46 | -------------------------------------------------------------------------------- /Graph/tree_diameter.h: -------------------------------------------------------------------------------- 1 | // Index from 0 2 | // g should contains both (u, v) and (v, u) 3 | // Return {length, path} 4 | // 5 | // Tested: 6 | // - https://judge.yosupo.jp/problem/tree_diameter 7 | // 8 | // Tree diameter (weighted) {{{ 9 | using ll = long long; 10 | pair> tree_diameter(const vector>>& g) { 11 | int n = g.size(); 12 | vector dist(n); 13 | vector parent(n); 14 | 15 | function dfs = [&] (int u, int fu, ll cur_dist) { 16 | dist[u] = cur_dist; 17 | parent[u] = fu; 18 | for (auto [v, cost] : g[u]) if (v != fu) { 19 | dfs(v, u, cur_dist + cost); 20 | } 21 | }; 22 | dfs(0, -1, 0); 23 | // r = furthest node from root 24 | int r = max_element(dist.begin(), dist.end()) - dist.begin(); 25 | dfs(r, -1, 0); 26 | // r->s = longest path 27 | int s = max_element(dist.begin(), dist.end()) - dist.begin(); 28 | 29 | vector path; 30 | for (int x = s; x >= 0; x = parent[x]) path.push_back(x); 31 | 32 | return {dist[s], path}; 33 | } 34 | // }}} 35 | -------------------------------------------------------------------------------- /Java/InputReader.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStream; 4 | import java.io.InputStreamReader; 5 | import java.util.StringTokenizer; 6 | 7 | class InputReader { 8 | private final BufferedReader reader; 9 | private StringTokenizer tokenizer; 10 | 11 | public InputReader(InputStream stream) { 12 | reader = new BufferedReader(new InputStreamReader(stream)); 13 | tokenizer = null; 14 | } 15 | 16 | public String nextLine() { 17 | try { 18 | return reader.readLine(); 19 | } catch (IOException e) { 20 | throw new RuntimeException(e); 21 | } 22 | } 23 | 24 | public String next() { 25 | while (tokenizer == null || !tokenizer.hasMoreTokens()) { 26 | tokenizer = new StringTokenizer(nextLine()); 27 | } 28 | return tokenizer.nextToken(); 29 | } 30 | 31 | public int nextInt() { 32 | return Integer.parseInt(next()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Java/JS.java: -------------------------------------------------------------------------------- 1 | package Java; 2 | import javax.script.*; 3 | 4 | public class JS { 5 | public static void main(String[] args) throws Exception { 6 | ScriptEngineManager manager = new ScriptEngineManager(); 7 | ScriptEngine engine = manager.getEngineByName("JavaScript"); 8 | 9 | String s = "(1 + 1) * 2"; 10 | engine.put("s", s); 11 | engine.eval("print('In JS, s = ' + s); s = eval(s);"); 12 | 13 | Integer t = (Integer) engine.get("s"); 14 | System.out.println("In Java, t = " + t); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Java/RegexTest.java: -------------------------------------------------------------------------------- 1 | package Java; 2 | import java.util.regex.*; 3 | public class RegexTest { 4 | public static void main(String[] args) { 5 | Pattern p = Pattern.compile("a+"); 6 | String s = "aabbbaaaaabbbabb"; 7 | System.out.println(s.matches("a+b+a+b+a+b+")); 8 | Matcher m = p.matcher(s); 9 | while (m.find()) { 10 | System.out.println(m.start() + "-->" + m.end() + ": " + m.group()); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Math/Linear/GaussianBinary.h: -------------------------------------------------------------------------------- 1 | // Tested: http://codeforces.com/gym/100211 - E 2 | // n : number of rows 3 | // m : number of columns 4 | int gauss (vector < bitset > a, int n, int m, bitset & ans) { 5 | vector where (m, -1); 6 | for (int col=0, row=0; col 6 | struct CRT { 7 | T res; 8 | 9 | CRT() { 10 | res = 0, prd = 1; 11 | } 12 | 13 | // Add condition: res % p == r 14 | void add(T p, T r) { 15 | res += mul(r - res % p + p, euclid(prd, p).first + p, p) * prd; 16 | prd *= p; 17 | if (res >= prd) res -= prd; 18 | } 19 | 20 | private: 21 | T prd; 22 | T mul(T a, T b, T p) { 23 | a %= p, b %= p; 24 | T q = (T) ((long double) a * b / p); 25 | T r = a * b - q * p; 26 | while (r < 0) r += p; 27 | while (r >= p) r -= p; 28 | return r; 29 | } 30 | pair euclid(T a, T b) { 31 | if (!b) return make_pair(1, 0); 32 | pair r = euclid(b, a % b); 33 | return make_pair(r.second, r.first - a / b * r.second); 34 | } 35 | }; 36 | // }}} 37 | -------------------------------------------------------------------------------- /Math/NumberTheory/ChineseRemainder.h: -------------------------------------------------------------------------------- 1 | // Solve linear congruences equation: 2 | // - a[i] * x = b[i] MOD m[i] (mi don't need to be co-prime) 3 | // Tested: 4 | // - https://open.kattis.com/problems/generalchineseremainder 5 | // - https://oj.vnoi.info/problem/icpc21_mt_d 6 | #include "ExtendedEuclid.h" 7 | template 8 | bool linearCongruences( 9 | const vector &a, 10 | const vector &b, 11 | const vector &m, 12 | T &x, 13 | T &M 14 | ) { 15 | int n = a.size(); 16 | x = 0; M = 1; 17 | for (int i = 0; i < n; i++) { 18 | T a_ = a[i] * M, b_ = b[i] - a[i] * x, m_ = m[i]; 19 | T y, t, g = extgcd(a_, m_, y, t); 20 | if (b_ % g) return false; 21 | b_ /= g; m_ /= g; 22 | x += M * (y * b_ % m_); 23 | M *= m_; 24 | } 25 | x = (x + M) % M; 26 | return true; 27 | } 28 | -------------------------------------------------------------------------------- /Math/NumberTheory/ExtendedEuclid.h: -------------------------------------------------------------------------------- 1 | // Dùng Extended Euclid để tìm nghiệm của phương trình ax + by = gcd(a, b). 2 | // Giả sử kết quả trả về là (x0, y0), họ nghiệm của phương trình sẽ là (x_0+kb/d,y_0-ka/d) với k∈Z. 3 | // Phương trình tổng quát ax + by = d chỉ có nghiệm khi d chia hết cho gcd(a, b). 4 | // a x + b y = gcd(a, b) 5 | template 6 | T extgcd(T a, T b, T &x, T &y) { 7 | T g = a; x = 1; y = 0; 8 | if (b != 0) g = extgcd(b, a % b, y, x), y -= (a / b) * x; 9 | return g; 10 | } 11 | -------------------------------------------------------------------------------- /Math/NumberTheory/FactorialMod.h: -------------------------------------------------------------------------------- 1 | int factmod (int n, int p) { // n!, excluding p^k of course 2 | int res = 1; 3 | while (n > 1) { 4 | res = (res * ((n/p) % 2 ? p-1 : 1)) % p; 5 | for (int i=2; i<=n%p; ++i) 6 | res = (res * i) % p; 7 | n /= p; 8 | } 9 | return res % p; 10 | } 11 | -------------------------------------------------------------------------------- /Math/NumberTheory/PrimitiveRoot.h: -------------------------------------------------------------------------------- 1 | // Primitive root of modulo n is integer g iff for all a < n & gcd(a, n) == 1, there exist k: g^k = a mod n 2 | // k is called discrete log of a (in case P is prime, can find in O(sqrt(P)) by noting that (P-1) is divisible by k) 3 | // 4 | // Exist if: 5 | // - n is 1, 2, 4 6 | // - n = p^k for odd prime p 7 | // - n = 2*p^k for odd prime p 8 | int powmod (int a, int b, int p) { 9 | int res = 1; 10 | while (b) 11 | if (b & 1) 12 | res = int (res * 1ll * a % p), --b; 13 | else 14 | a = int (a * 1ll * a % p), b >>= 1; 15 | return res; 16 | } 17 | 18 | int generator (int p) { 19 | vector fact; 20 | int phi = p-1, n = phi; 21 | for (int i=2; i*i<=n; ++i) 22 | if (n % i == 0) { 23 | fact.push_back (i); 24 | while (n % i == 0) 25 | n /= i; 26 | } 27 | if (n > 1) 28 | fact.push_back (n); 29 | 30 | for (int res=2; res<=p; ++res) { 31 | bool ok = true; 32 | for (size_t i=0; i 0); 7 | auto ps = factorize(n); 8 | int cnt_ps = ps.size(); 9 | int i = 0; 10 | int64_t res = 1; 11 | while (i < cnt_ps) { 12 | int j = i; 13 | while (j+1 < cnt_ps && ps[j+1] == ps[j]) ++j; 14 | res *= j - i + 2; 15 | i = j + 1; 16 | } 17 | return res; 18 | } 19 | 20 | // Count divisors Using Segmented Sieve O(sieve(sqrt(R)) + (R-L)*log) {{{ 21 | // Returns vector of length (r - l + 1), where the i-th element is number of 22 | // divisors of i - l 23 | vector cnt_divisors_segmented_sieve(int l, int r) { 24 | int s = sqrt(r + 0.5); 25 | vector primes; 26 | auto newPrime = [&] (int p) { primes.push_back(p); }; 27 | sieve(s, newPrime); 28 | 29 | vector cnt(r - l + 1, 1), cur(r - l + 1); 30 | std::iota(cur.begin(), cur.end(), l); 31 | 32 | for (int p : primes) { 33 | if (p > r) break; 34 | 35 | int u = (l + p - 1) / p * p; 36 | for (int i = u; i <= r; i += p) { 37 | int k = 0; 38 | while (cur[i-l] % p == 0) cur[i-l] /= p, ++k; 39 | 40 | cnt[i - l] *= k + 1; 41 | } 42 | } 43 | for (int i = l; i <= r; ++i) { 44 | if (cur[i-l] > 1) cnt[i-l] *= 2; 45 | } 46 | return cnt; 47 | } 48 | // }}} 49 | -------------------------------------------------------------------------------- /Math/NumberTheory/congruence.h: -------------------------------------------------------------------------------- 1 | // Giải phương trình: a1x1 + a2x2 + … + anxn ≡ b (modul m) 2 | // Trong đó a1, a2, …, an, b, m là các số nguyên dương. 3 | 4 | int g[MAXN], x[MAXN]; 5 | 6 | bool congruenceEquation(vector a, int b, int m, vector &ret) { 7 | int n = sz(a); 8 | a.pb(m); 9 | g[0] = a[0]; 10 | For(i, 1, n) g[i] = gcd(g[i - 1], a[i]); 11 | ret.clear(); 12 | if (b % g[n]) return false; 13 | int val = b / g[n]; 14 | Ford(i, n, 1) { 15 | pair p = extgcd(g[i - 1], a[i]); 16 | x[i] = p.se * val % m; 17 | val = p.fi * val % m; 18 | } 19 | x[0] = val; 20 | For(i, 0, n) x[i] = (x[i] + m) % m; 21 | Rep(i, n) ret.pb(x[i]); 22 | return true; 23 | } 24 | -------------------------------------------------------------------------------- /Math/Polynomial/FormalPowerSeries.h: -------------------------------------------------------------------------------- 1 | // Formal Power Series {{{ 2 | // 3 | // Notes: 4 | // - T must be ModInt 5 | 6 | #include "NTT.h" 7 | template struct FormalPowerSeries : std::vector { 8 | using std::vector::vector; 9 | using P = FormalPowerSeries; 10 | 11 | // Remove zeroes at the end 12 | void shrink() { 13 | while (!this->empty() && this->back() == T(0)) this->pop_back(); 14 | } 15 | 16 | // basic operators with another FPS: + - * / % {{{ 17 | P operator + (const P& r) { return P(*this) += r; } 18 | P operator - (const P& r) { return P(*this) -= r; } 19 | P operator * (const P& r) { return P(*this) *= r; } 20 | 21 | P& operator += (const P& r) { 22 | if (r.size() > this->size()) this->resize(r.size()); 23 | for (int i = 0; i < static_cast (r.size()); ++i) 24 | (*this)[i] += r[i]; 25 | shrink(); 26 | return *this; 27 | } 28 | P& operator -= (const P& r) { 29 | if (r.size() > this->size()) this->resize(r.size()); 30 | for (int i = 0; i < static_cast (r.size()); ++i) 31 | (*this)[i] -= r[i]; 32 | shrink(); 33 | return *this; 34 | } 35 | P& operator *= (const P& r) { 36 | if (this->empty() || r.empty()) { 37 | this->clear(); 38 | } else { 39 | auto res = multiply(*this, r); 40 | *this = P(res.begin(), res.end()); 41 | } 42 | return *this; 43 | } 44 | // }}} 45 | }; 46 | // }}} 47 | -------------------------------------------------------------------------------- /Math/Polynomial/Karatsuba.h: -------------------------------------------------------------------------------- 1 | // Copied from team TwT514 (Shik + takaramono + coquelicot) 2 | // Tested: 3 | // - https://open.kattis.com/problems/polymul2 4 | // - http://codeforces.com/gym/100341 - C 5 | // Notes: 6 | // - n must be power of 2. Remember to memset a, b, c to 0 7 | ll buf[10000000],*ptr=buf; 8 | void mul( int n, ll *a, ll *b, ll *c ) { 9 | if ( n<=32 ) { 10 | REP(i,2*n) c[i]=0; 11 | REP(i,n) REP(j,n) c[i+j]+=a[i]*b[j]; 12 | REP(i,2*n) c[i]%=MOD; 13 | return; 14 | } 15 | int m=n/2; 16 | ll *s1=ptr; ptr+=n; 17 | ll *s2=ptr; ptr+=n; 18 | ll *s3=ptr; ptr+=n; 19 | ll *aa=ptr; ptr+=m; 20 | ll *bb=ptr; ptr+=m; 21 | REP(i,m) { 22 | aa[i]=a[i]+a[i+m]; 23 | bb[i]=b[i]+b[i+m]; 24 | if ( aa[i]>=MOD ) aa[i]-=MOD; 25 | if ( bb[i]>=MOD ) bb[i]-=MOD; 26 | } 27 | mul(m,a,b,s1); 28 | mul(m,a+m,b+m,s2); 29 | mul(m,aa,bb,s3); 30 | memcpy(c,s1,n*sizeof(ll)); 31 | memcpy(c+n,s2,n*sizeof(ll)); 32 | REP(i,n) c[i+m]+=s3[i]-s1[i]-s2[i]; 33 | REP(i,2*n) c[i]%=MOD; 34 | ptr-=4*n; 35 | } 36 | // mul(2^x, a, b, c); REP(i,2*n) c[i] = (c[i] % MOD + MOD) % MOD 37 | -------------------------------------------------------------------------------- /Math/Polynomial/PolynomialValues.h: -------------------------------------------------------------------------------- 1 | // m = number of known points 2 | // o = number of unknown points 3 | // d[0] = values of known points 4 | /* calculate differences */ 5 | for(i=0;i=0;i--) 10 | d[i][m-1]+=d[i+1][m-1] ; 11 | printf("%d%c",d[0][m-1], (j==o-1)?'\n':' '); 12 | } 13 | -------------------------------------------------------------------------------- /Math/Prime/RabinMiller32.h: -------------------------------------------------------------------------------- 1 | // Tested: 2 | // - https://www.spoj.com/problems/PRIC/ 3 | 4 | #include 5 | // Rabin Miller for 32-bit numbers {{{ 6 | inline unsigned mod_mult(unsigned a, unsigned b, unsigned m) { 7 | return (uint64_t)a*b%m; 8 | } 9 | 10 | unsigned mod_pow(unsigned a, uint64_t b, unsigned m) { 11 | unsigned ret = 1; 12 | for(;;) { 13 | if (b&1) ret = mod_mult(ret, a, m); 14 | if (!(b>>=1)) return ret; 15 | a = mod_mult(a, a, m); 16 | } 17 | } 18 | 19 | bool is_prime(unsigned n) { 20 | if (n <= 3) return (n >= 2); 21 | static const unsigned small[] = { 22 | 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 23 | 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 24 | }; 25 | for (size_t i = 0; i < sizeof(small)/sizeof(unsigned); i++) { 26 | if (n%small[i] == 0) return n == small[i]; 27 | } 28 | 29 | // Jaeschke93 showed that 2,7,61 suffice for n < 4,759,123,141. 30 | static const unsigned millerrabin[] = {2, 7, 61}; 31 | unsigned s = n-1, r = 0; 32 | while (s%2 == 0) {s /= 2; r++;} 33 | 34 | for (size_t i = 0, j; i < sizeof(millerrabin)/sizeof(unsigned); i++) { 35 | unsigned md = mod_pow(millerrabin[i], s, n); 36 | if (md == 1) continue; 37 | for (j = 1; j < r; j++) { 38 | if (md == n-1) break; 39 | md = mod_mult(md, md, n); 40 | } 41 | if (md != n-1) return false; 42 | } 43 | 44 | return true; 45 | } 46 | // }}} 47 | -------------------------------------------------------------------------------- /Math/Prime/SegmentedSieve.h: -------------------------------------------------------------------------------- 1 | // table[i-L] == true <=> i == prime 2 | const int SQRTN = 1<<16; // upperbound of sqrt(H) + 10 3 | 4 | // [L, H) 5 | vector segmentSieve(ll L, ll H) { 6 | static ll p[SQRTN]; 7 | static int lookup = 0; 8 | if (!lookup) { 9 | for (ll i = 2; i < SQRTN; ++i) p[i] = i; 10 | for (ll i = 2; i*i < SQRTN; ++i) 11 | if (p[i]) 12 | for (ll j = i*i; j < SQRTN; j += i) 13 | p[j] = 0; 14 | remove(p, p+SQRTN, 0); 15 | lookup = 1; 16 | } 17 | vector table(H - L); 18 | for (ll i = L; i < H; ++i) table[i - L] = 1; 19 | for (ll i = 0, j; p[i] * p[i] < H; ++i) { // O( \sqrt(H) ) 20 | if (p[i] >= L) j = p[i] * p[i]; 21 | else if (L % p[i] == 0) j = L; 22 | else j = L - (L % p[i]) + p[i]; 23 | for (; j < H; j += p[i]) table[j-L] = 0; 24 | } 25 | return table; 26 | } 27 | -------------------------------------------------------------------------------- /Math/Prime/Sieve.h: -------------------------------------------------------------------------------- 1 | // F is called for each prime 2 | // Sieve (odd only + segmented) {{{ 3 | template 4 | void sieve(int MAX, F func) { 5 | 6 | const int S = sqrt(MAX + 0.5); 7 | vector sieve(S + 1, true); 8 | vector> cp; 9 | for (int i = 3; i <= S; i += 2) { 10 | if (!sieve[i]) 11 | continue; 12 | cp.push_back({i, (i * i - 1) / 2}); 13 | for (int j = i * i; j <= S; j += 2 * i) 14 | sieve[j] = false; 15 | } 16 | func(2); 17 | vector block(S); 18 | int high = (MAX - 1) / 2; 19 | for (int low = 0; low <= high; low += S) { 20 | fill(block.begin(), block.end(), true); 21 | for (auto &i : cp) { 22 | int p = i[0], idx = i[1]; 23 | for (; idx < S; idx += p) 24 | block[idx] = false; 25 | i[1] = idx - S; 26 | } 27 | if (low == 0) 28 | block[0] = false; 29 | for (int i = 0; i < S && low + i <= high; i++) 30 | if (block[i]) { 31 | func((low + i) * 2 + 1); 32 | } 33 | }; 34 | } 35 | // }}} 36 | -------------------------------------------------------------------------------- /Math/Pure/Cubic.h: -------------------------------------------------------------------------------- 1 | const double EPS = 1e-6; 2 | struct Result { 3 | int n; // Number of solutions 4 | double x[3]; // Solutions 5 | }; 6 | Result solve_cubic(double a, double b, double c, double d) { 7 | long double a1 = b/a, a2 = c/a, a3 = d/a; 8 | long double q = (a1*a1 - 3*a2)/9.0, sq = -2*sqrt(q); 9 | long double r = (2*a1*a1*a1 - 9*a1*a2 + 27*a3)/54.0; 10 | double z = r*r-q*q*q, theta; 11 | Result s; 12 | if(z <= EPS) { 13 | s.n = 3; theta = acos(r/sqrt(q*q*q)); 14 | s.x[0] = sq*cos(theta/3.0) - a1/3.0; 15 | s.x[1] = sq*cos((theta+2.0*PI)/3.0) - a1/3.0; 16 | s.x[2] = sq*cos((theta+4.0*PI)/3.0) - a1/3.0; 17 | } 18 | else { 19 | s.n = 1; s.x[0] = pow(sqrt(z)+fabs(r),1/3.0); 20 | s.x[0] += q/s.x[0]; s.x[0] *= (r < 0) ? 1 : -1; 21 | s.x[0] -= a1/3.0; 22 | } 23 | return s; 24 | } 25 | -------------------------------------------------------------------------------- /Math/Pure/PythagoreTriple.h: -------------------------------------------------------------------------------- 1 | // sinh bo 3 pytago nguyen thuy voi x, y, z <= n 2 | vector< vector > genPrimitivePytTriples(int n) { 3 | vector< vector > ret; 4 | for (int r=1; r*r<=n; ++r) for (int s=(r%2==0)?1:2; s t; 6 | t.push_back(r*r+s*s); //z 7 | t.push_back(2*r*s); // y 8 | t.push_back(r*r-s*s); // x 9 | if (t[0]<=n) ret.push_back(t); 10 | } 11 | sort(ret.begin(), ret.end()); 12 | return ret; 13 | } 14 | // a^2 + b^2 == c^2 15 | // To generate all primitive triples: 16 | // a = m^2 - n^2, b = 2mn, c = m^2 + n^2 (m > n) 17 | // Primitive triples iff gcd(m, n) == 1 && (m - n) % 2 == 1 18 | -------------------------------------------------------------------------------- /Math/Pure/farey.h: -------------------------------------------------------------------------------- 1 | // Farey sequence (denominator <= N) enumeration: 2 | // Properties 3 | // 1. Two fractions: 0 <= a/b < c/d <= 1 are neighbors in some Farey sequence iff b*c - a*d == 1 4 | // 2. If b*c - a*d == 1, the (unique) fraction between a/b and c/d with smallest denominator is (a+c) / (b+d) 5 | // 3. If a/b < c/d < e/f are 3 consecutives fraction in some Farey sequence, then c/d = (a+e) / (b+f) 6 | 7 | int N = 12000; 8 | pair next(int a, int b, int c, int d) { 9 | int k = (N + b) / d; 10 | return make_pair(k*c - a, k*d - b); 11 | } 12 | // To find c/d using only a/b: 13 | // Using extended euclid, we can find c0, d0 such that b*c0 - a*d0 == 1 14 | // c = c0 + (N - d0)/b * a 15 | // d = d0 + (N - d0)/b * b 16 | 17 | // To count number of fractions in range (x, y): 18 | // F(N) = count(k/n : x < k/n < y and n <= N) 19 | // R(N) = count(k/n : x < k/n < y and n <= N and gcd(k,n) == 1) 20 | // F(N) can be easily calculated in O(N) 21 | // F(N) = sum( R(N div m) for m = 1..N ) 22 | // Thus R(N) can be calculated using generalized inversed Moebius formula 23 | -------------------------------------------------------------------------------- /Math/Pure/fibo.h: -------------------------------------------------------------------------------- 1 | // Proof : http://www.fq.math.ca/Scanned/10-4/advanced10-4.pdf 2 | bool isSquare(long long n) { /* */} 3 | bool isFibonacci(int n) { 4 | return n >= 0 && isSquare(5*n*n+4) || isSquare(5*n*n-4); 5 | } 6 | -------------------------------------------------------------------------------- /Math/Pure/lagrange.h: -------------------------------------------------------------------------------- 1 | // http://codeforces.com/blog/entry/23442 2 | // Polynomial P of degree N --> need N+1 points. Let n = N+1 3 | // init y[i], i = 1..n 4 | // init coefficient: 5 | FOR(i,1,n) f[i] = (x - i + MOD) % MOD; 6 | l[0] = 1; FOR(i,1,n) l[i] = l[i-1] * f[i] % MOD; 7 | r[n+1] = 1; FORD(i,n,1) r[i] = r[i+1] * f[i] % MOD; 8 | // P(x) = sum(y[i] * product((x - j) / (i - j), j=1..n, j != i), i=1..n) 9 | int res = 0; 10 | FOR(i,1,n) { 11 | // j < i 12 | int cur = l[i-1] * inv_gt[i - 1] % MOD; 13 | // j > i 14 | cur = cur * r[i+1] % MOD * inv_gt[n - i] % MOD; 15 | if ((n - i) % 2) cur = cur * (MOD - 1) % MOD; 16 | // add y[i] * product 17 | res = (res + cur * y[i]) % MOD; 18 | } 19 | -------------------------------------------------------------------------------- /Math/Pure/moebius.txt: -------------------------------------------------------------------------------- 1 | If g and f are arithmetic functions satisfying: 2 | g(n) = sum( f(d) for d|n ) 3 | then 4 | f(n) = sum( mu(d)*g(n/d) for d|n ) 5 | 6 | where mu(n) is: 7 | 0 if n has squared prime factor 8 | 1 if n is square-free and has even number of prime factor 9 | -1 if n is square-free and has odd number of prime factor 10 | 11 | Generalized version: 12 | g(n) = sum( f(n div m) for 1 <= m <= n) 13 | then 14 | f(n) = sum( mu(m) * g(n div m) for 1 <= m <= n) 15 | 16 | -------------------------------------------------------------------------------- /Math/Pure/n_gonal.txt: -------------------------------------------------------------------------------- 1 | Polygonal numbers: # dots arranged in shape of regular polygon. 2 | 3. n*(n+1)/2 3 | 4. n*n 4 | 5. n*(3*n-1)/2 5 | 6. n*(2*n-1) 6 | s. P(s, n) = (n*n*(s-2) - n*(s-4))/2 7 | 2*P(s, n) = P(s+k, n) + P(s-k, n) 8 | 9 | -------------------------------------------------------------------------------- /Math/SumDiv_SumMod.h: -------------------------------------------------------------------------------- 1 | // Copied from https://judge.yosupo.jp/submission/15864 2 | // Tested: 3 | // - https://judge.yosupo.jp/problem/sum_of_floor_of_linear 4 | 5 | using ll = long long; 6 | ll sum(ll n) { 7 | return n * (n-1) / 2; 8 | } 9 | // sum( (a + d*i) / m ) for i in [0, n-1] 10 | ll sum_div(ll a, ll d, ll m, ll n) { 11 | ll res = d / m * sum(n) + a / m * n; 12 | d %= m, a %= m; 13 | if (!d) return res; 14 | ll to = (n * d + a) / m; 15 | return res + (n - 1) * to - sum_div(m - 1 - a, m, d, to); 16 | } 17 | // sum( (a + d*i) % m ) for i in [0, n-1] 18 | ll sum_mod(ll a, ll d, ll m, ll n) { 19 | a = ((a % m) + m) % m, d = ((d % m) + m) % m; 20 | return n * a + d * sum(n) - m * sum_div(a, d, m, n); 21 | } 22 | -------------------------------------------------------------------------------- /Math/modulo.h: -------------------------------------------------------------------------------- 1 | /** 2 | * When MOD < 2^63, use following mulMod: 3 | * Source: https://en.wikipedia.org/wiki/Modular_arithmetic#Example_implementations 4 | * On computer architectures where an extended precision format with at least 64 bits 5 | * of mantissa is available (such as the long double type of most x86 C compilers), 6 | * the following routine is faster than any algorithmic solution, by employing the 7 | * trick that, by hardware, floating-point multiplication results in the most 8 | * significant bits of the product kept, while integer multiplication results in the 9 | * least significant bits kept 10 | */ 11 | uint64_t mulMod(uint64_t a, uint64_t b, uint64_t m) { 12 | long double x; 13 | uint64_t c; 14 | int64_t r; 15 | 16 | if (a >= m) a %= m; 17 | if (b >= m) b %= m; 18 | 19 | x = a; 20 | c = x * b / m; 21 | r = (int64_t)(a * b - c * m) % (int64_t)m; 22 | return r < 0 ? r + m : r; 23 | } 24 | 25 | /** Calculates a^b % m */ 26 | uint64_t powMod(uint64_t a, uint64_t b, uint64_t m) { 27 | uint64_t r = m==1?0:1; // make it works when m == 1. 28 | while (b > 0) { 29 | if (b & 1) r = mulMod(r, a, m); 30 | b = b >> 1; 31 | a = mulMod(a, a, m); 32 | } 33 | return r; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /Math/tests/.gitignore: -------------------------------------------------------------------------------- 1 | in 2 | -------------------------------------------------------------------------------- /Math/tests/aizu_ntl_1_a_factorize.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_1_A" 2 | 3 | #include "../../template.h" 4 | #include "../NumberTheory/Pollard_factorize.h" 5 | 6 | void solve() { 7 | int n; 8 | cin >> n; 9 | auto facs = factorize(n); 10 | cout << n << ':'; 11 | for (auto x : facs) cout << ' ' << x; 12 | cout << '\n'; 13 | } 14 | -------------------------------------------------------------------------------- /Math/tests/aizu_ntl_1_b_modulo_pow.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_1_B" 2 | 3 | #include "../../template.h" 4 | #include "../modint.h" 5 | 6 | const int MOD = 1e9 + 7; 7 | using modular = ModInt; 8 | 9 | void solve() { 10 | modular m; int k; cin >> m >> k; 11 | cout << m.pow(k) << endl; 12 | } 13 | -------------------------------------------------------------------------------- /Math/tests/aizu_ntl_1_d_euler_phi.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_1_D" 2 | 3 | #include "../../template.h" 4 | #include "../Prime/EulerPhi.h" 5 | 6 | using ll = long long; 7 | void solve() { 8 | ll n; cin >> n; 9 | if (n < N) { 10 | assert(eulerPhi(n) == eulerPhi_lookup(n)); 11 | } 12 | cout << eulerPhi(n) << endl; 13 | } 14 | -------------------------------------------------------------------------------- /Math/tests/aizu_ntl_1_e_extended_euclid.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_1_E" 2 | 3 | #include "../../template.h" 4 | #include "../NumberTheory/ExtendedEuclid.h" 5 | 6 | using ll = long long; 7 | void solve() { 8 | ll a, b; cin >> a >> b; 9 | ll x, y; 10 | extgcd(a, b, x, y); 11 | cout << x << ' ' << y << endl; 12 | } 13 | -------------------------------------------------------------------------------- /Math/tests/aizu_ntl_2_a_bigint_add.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_2_A" 2 | 3 | #include "../../template.h" 4 | #include "../bigint.h" 5 | 6 | void solve() { 7 | BigInt a, b; cin >> a >> b; 8 | cout << a + b << endl; 9 | } 10 | -------------------------------------------------------------------------------- /Math/tests/aizu_ntl_2_b_bigint_sub.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_2_B" 2 | 3 | #include "../../template.h" 4 | #include "../bigint.h" 5 | 6 | void solve() { 7 | BigInt a, b; cin >> a >> b; 8 | cout << a - b << endl; 9 | } 10 | -------------------------------------------------------------------------------- /Math/tests/aizu_ntl_2_c_bigint_mul.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_2_C" 2 | 3 | #include "../../template.h" 4 | #include "../bigint.h" 5 | 6 | void solve() { 7 | BigInt a, b; cin >> a >> b; 8 | cout << a * b << endl; 9 | } 10 | -------------------------------------------------------------------------------- /Math/tests/aizu_ntl_2_c_bigint_mul_karatsuba.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_2_C" 2 | 3 | #include "../../template.h" 4 | #include "../bigint.h" 5 | 6 | void solve() { 7 | BigInt a, b; cin >> a >> b; 8 | cout << a.mul_karatsuba(b) << endl; 9 | } 10 | -------------------------------------------------------------------------------- /Math/tests/aizu_ntl_2_d_bigint_div.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_2_D" 2 | 3 | #include "../../template.h" 4 | #include "../bigint.h" 5 | 6 | void solve() { 7 | BigInt a, b; cin >> a >> b; 8 | cout << a / b << endl; 9 | } 10 | -------------------------------------------------------------------------------- /Math/tests/aizu_ntl_2_e_bigint_mod.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_2_E" 2 | 3 | #include "../../template.h" 4 | #include "../bigint.h" 5 | 6 | void solve() { 7 | BigInt a, b; cin >> a >> b; 8 | cout << a % b << endl; 9 | } 10 | -------------------------------------------------------------------------------- /Math/tests/aizu_ntl_2_f_bigint_mul_fft.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_2_F" 2 | 3 | #include "../../template.h" 4 | #include "../bigint.h" 5 | 6 | void solve() { 7 | BigInt a, b; cin >> a >> b; 8 | cout << a * b << endl; 9 | } 10 | -------------------------------------------------------------------------------- /Math/tests/berlekamp_massey.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/find_linear_recurrence" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../modint.h" 7 | 8 | using modular = ModInt<998244353>; 9 | 10 | #include "../LinearRecurrence_BerlekampMassey.h" 11 | 12 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 13 | #define SZ(x) ((int)(x).size()) 14 | 15 | int32_t main() { 16 | ios::sync_with_stdio(0); cin.tie(0); 17 | int n; cin >> n; 18 | vector a(n); 19 | REP(i,n) cin >> a[i]; 20 | 21 | vector c = berlekampMassey(a); 22 | cout << SZ(c) << endl; 23 | for (auto x : c) cout << x << ' '; 24 | cout << endl; 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Math/tests/cnt_divisors_stress.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_1_A" 2 | 3 | #include "../../template.h" 4 | #include "../NumberTheory/cnt_divisors.h" 5 | #include "../multiplicative_function.h" 6 | 7 | const int N = 1000000; 8 | MultiplicativeFunction mf; 9 | auto divisors = mf.divisors(); 10 | 11 | #include "../multiplicative_functions_linear.h" 12 | 13 | void solve() { 14 | linear_sieve::linear_sieve_divisors(N + 1); 15 | for (int i = 1; i <= N; ++i) { 16 | assert(divisors[i] == cnt_divisors(i)); 17 | assert(divisors[i] == linear_sieve::cnt_divisors[i]); 18 | } 19 | cout << "Hello World\n"; 20 | } 21 | -------------------------------------------------------------------------------- /Math/tests/convolution_and.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/bitwise_and_convolution" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../Polynomial/xorFFT.h" 7 | 8 | long long a[1<<20], b[1<<20]; 9 | const int MOD = 998244353; 10 | 11 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 12 | 13 | int32_t main() { 14 | ios::sync_with_stdio(0); cin.tie(0); 15 | int n; cin >> n; 16 | n = 1 << n; 17 | REP(i,n) cin >> a[i]; 18 | REP(i,n) cin >> b[i]; 19 | 20 | andFFT(a, n, MOD, 0); 21 | andFFT(b, n, MOD, 0); 22 | REP(i,n) a[i] = a[i] * b[i] % MOD; 23 | 24 | andFFT(a, n, MOD, 1); 25 | 26 | REP(i,n) cout << a[i] << ' '; 27 | cout << endl; 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Math/tests/convolution_xor.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/bitwise_xor_convolution" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #define int long long 7 | #include "../Polynomial/xorFFT.h" 8 | 9 | long long a[1<<20], b[1<<20]; 10 | const int MOD = 998244353; 11 | 12 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 13 | 14 | int32_t main() { 15 | ios::sync_with_stdio(0); cin.tie(0); 16 | int n; cin >> n; 17 | n = 1 << n; 18 | REP(i,n) cin >> a[i]; 19 | REP(i,n) cin >> b[i]; 20 | 21 | xorFFT(a, n, MOD, 0); 22 | xorFFT(b, n, MOD, 0); 23 | REP(i,n) a[i] = a[i] * b[i] % MOD; 24 | 25 | xorFFT(a, n, MOD, 1); 26 | 27 | REP(i,n) cout << a[i] << ' '; 28 | cout << endl; 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Math/tests/euler_phi_stress.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_1_A" 2 | 3 | #include "../../template.h" 4 | #include "../Prime/EulerPhi.h" 5 | #include "../multiplicative_functions_linear.h" 6 | 7 | void solve() { 8 | linear_sieve::linear_sieve_phi(N); 9 | for (int i = 1; i < N; ++i) { 10 | assert(linear_sieve::phi[i] == eulerPhi(i)); 11 | assert(linear_sieve::phi[i] == eulerPhi_lookup(i)); 12 | } 13 | cout << "Hello World\n"; 14 | } 15 | -------------------------------------------------------------------------------- /Math/tests/factorize.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/factorize" 2 | 3 | #include 4 | using namespace std; 5 | 6 | // for 64-bit, use mt19937_64 7 | mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); 8 | long long get_rand(long long r) { 9 | return uniform_int_distribution (0, r-1)(rng); 10 | } 11 | 12 | #include "../NumberTheory/Pollard_factorize.h" 13 | 14 | int32_t main() { 15 | ios::sync_with_stdio(0); cin.tie(0); 16 | int ntest; cin >> ntest; 17 | while (ntest--) { 18 | long long n; cin >> n; 19 | auto f = factorize(n); 20 | cout << f.size(); 21 | for (auto x : f) cout << ' ' << x; 22 | cout << '\n'; 23 | } 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Math/tests/formal_power_series_multiply.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod" 2 | 3 | #include 4 | 5 | #include "../modint.h" 6 | #include "../Polynomial/FormalPowerSeries.h" 7 | 8 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 9 | using mint = ModInt<998244353>; 10 | 11 | int32_t main() { 12 | int n, m; std::cin >> n >> m; 13 | FormalPowerSeries a(n), b(m); 14 | for (auto& val : a) std::cin >> val; 15 | for (auto& val : b) std::cin >> val; 16 | 17 | auto c = a * b; 18 | for (auto val : c) std::cout << val << ' '; 19 | std::cout << std::endl; 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /Math/tests/formal_power_series_multiply_any_mod.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod_1000000007" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../modint.h" 7 | #include "../Polynomial/FormalPowerSeries.h" 8 | 9 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 10 | using mint = ModInt<1'000'000'007>; 11 | 12 | int32_t main() { 13 | int n, m; std::cin >> n >> m; 14 | FormalPowerSeries a(n), b(m); 15 | for (auto& val : a) std::cin >> val; 16 | for (auto& val : b) std::cin >> val; 17 | 18 | auto c = a * b; 19 | for (auto val : c) std::cout << val << ' '; 20 | std::cout << std::endl; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Math/tests/is_prime_yukicoder.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://yukicoder.me/problems/no/3030" 2 | 3 | #include "../../template.h" 4 | #include "../NumberTheory/Pollard_factorize.h" 5 | 6 | void solve() { 7 | int q; cin >> q; 8 | while (q--) { 9 | long long n; 10 | cin >> n; 11 | cout << n << ' ' << isPrime(n) << '\n'; 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /Math/tests/matrix_det.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/matrix_det" 2 | 3 | #include 4 | #include "../../atcoder/modint.hpp" 5 | using namespace std; 6 | using namespace atcoder; 7 | 8 | #include "../Matrix.h" 9 | #include "../../buffered_reader.h" 10 | 11 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 12 | 13 | int32_t main() { 14 | ios::sync_with_stdio(0); cin.tie(0); 15 | int n = IO::get(); 16 | Matrix a(n, n); 17 | REP(i,n) REP(j,n) { 18 | int x = IO::get(); 19 | a[i][j] = x; 20 | } 21 | auto tmp = a.gauss(); 22 | cout << tmp.det().val() << endl; 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Math/tests/matrix_inverse.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/inverse_matrix" 2 | 3 | #include 4 | #include "../../atcoder/modint.hpp" 5 | using namespace std; 6 | using namespace atcoder; 7 | 8 | #include "../Matrix.h" 9 | #include "../../buffered_reader.h" 10 | 11 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 12 | 13 | int32_t main() { 14 | ios::sync_with_stdio(0); cin.tie(0); 15 | int n = IO::get(); 16 | Matrix a(n, n); 17 | REP(i,n) REP(j,n) { 18 | int x = IO::get(); 19 | a[i][j] = x; 20 | } 21 | int rank = a.inverse(); 22 | if (rank < n) cout << -1 << '\n'; 23 | else { 24 | REP(i,n) { 25 | REP(j,n) cout << a[i][j].val() << ' '; 26 | cout << '\n'; 27 | } 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Math/tests/matrix_mult.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/matrix_product" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../Matrix.h" 7 | #include "../../buffered_reader.h" 8 | #include "../modint.h" 9 | 10 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 11 | using modular = ModInt<998244353>; 12 | 13 | int32_t main() { 14 | ios::sync_with_stdio(0); cin.tie(0); 15 | int n = IO::get(); 16 | int m = IO::get(); 17 | int k = IO::get(); 18 | Matrix a(n, m); 19 | Matrix b(m, k); 20 | for (auto& x : a.x) x = IO::get(); 21 | for (auto& x : b.x) x = IO::get(); 22 | 23 | auto c = a * b; 24 | REP(i,n) { 25 | REP(j,k) cout << c[i][j] << ' '; 26 | cout << '\n'; 27 | } 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /Math/tests/nimber.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/nim_product_64" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../nim_product.h" 7 | 8 | int32_t main() { 9 | ios::sync_with_stdio(0); cin.tie(0); 10 | int ntest; cin >> ntest; 11 | while (ntest--) { 12 | ull x, y; cin >> x >> y; 13 | cout << mult(x, y) << '\n'; 14 | } 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /Math/tests/ntt.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../modint.h" 7 | #include "../Polynomial/NTT.h" 8 | 9 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 10 | using mint = ModInt<998244353>; 11 | 12 | int32_t main() { 13 | ios::sync_with_stdio(0); cin.tie(0); 14 | int n, m; cin >> n >> m; 15 | vector a(n); REP(i,n) cin >> a[i]; 16 | vector b(m); REP(i,m) cin >> b[i]; 17 | 18 | auto c = multiply(a, b); 19 | for (auto x : c) cout << x << ' '; 20 | cout << endl; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Math/tests/ntt_any_mod.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod_1000000007" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../modint.h" 7 | #include "../Polynomial/NTT.h" 8 | 9 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 10 | using mint = ModInt<1'000'000'007>; 11 | 12 | int32_t main() { 13 | ios::sync_with_stdio(0); cin.tie(0); 14 | int n, m; cin >> n >> m; 15 | vector a(n); REP(i,n) cin >> a[i]; 16 | vector b(m); REP(i,m) cin >> b[i]; 17 | 18 | auto c = multiply(a, b); 19 | for (const auto& val : c) cout << val << ' '; 20 | cout << endl; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Math/tests/ntt_chemthan.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../Polynomial/NTT_chemthan.h" 7 | 8 | NTT<998244353, 1<<20> ntt; 9 | 10 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 11 | 12 | int32_t main() { 13 | ios::sync_with_stdio(0); cin.tie(0); 14 | int n, m; cin >> n >> m; 15 | vector a(n); REP(i,n) cin >> a[i]; 16 | vector b(m); REP(i,m) cin >> b[i]; 17 | 18 | auto c = ntt.multiply(a, b); 19 | for (int x : c) cout << x << ' '; 20 | cout << endl; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Math/tests/ntt_chemthan_any_mod.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod_1000000007" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../Polynomial/NTT_chemthan.h" 7 | #include "../NumberTheory/CRT_chemthan.h" 8 | 9 | const int MOD0 = 167772161; 10 | const int MOD1 = 469762049; 11 | const int MOD2 = 754974721; 12 | NTT ntt0; 13 | NTT ntt1; 14 | NTT ntt2; 15 | 16 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 17 | 18 | int32_t main() { 19 | ios::sync_with_stdio(0); cin.tie(0); 20 | int n, m; cin >> n >> m; 21 | vector a(n); REP(i,n) cin >> a[i]; 22 | vector b(m); REP(i,m) cin >> b[i]; 23 | 24 | auto c0 = ntt0.multiply(a, b); 25 | auto c1 = ntt1.multiply(a, b); 26 | auto c2 = ntt2.multiply(a, b); 27 | 28 | const int MOD = 1e9 + 7; 29 | REP(i,n+m-1) { 30 | CRT<__int128_t> crt; 31 | crt.add(MOD0, c0[i]); 32 | crt.add(MOD1, c1[i]); 33 | crt.add(MOD2, c2[i]); 34 | cout << (int) (crt.res % MOD) << ' '; 35 | } 36 | cout << endl; 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /Math/tests/ntt_chemthan_any_mod_2.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod_1000000007" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../Polynomial/NTT_chemthan.h" 7 | #include "../NumberTheory/ChineseRemainder.h" 8 | 9 | const int MOD0 = 167772161; 10 | const int MOD1 = 469762049; 11 | const int MOD2 = 754974721; 12 | NTT ntt0; 13 | NTT ntt1; 14 | NTT ntt2; 15 | 16 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 17 | 18 | int32_t main() { 19 | ios::sync_with_stdio(0); cin.tie(0); 20 | int n, m; cin >> n >> m; 21 | vector a(n); REP(i,n) cin >> a[i]; 22 | vector b(m); REP(i,m) cin >> b[i]; 23 | 24 | auto c0 = ntt0.multiply(a, b); 25 | auto c1 = ntt1.multiply(a, b); 26 | auto c2 = ntt2.multiply(a, b); 27 | 28 | const int MOD = 1e9 + 7; 29 | REP(i,n+m-1) { 30 | __int128_t x, _m; 31 | linearCongruences<__int128_t> ( 32 | {1, 1, 1}, 33 | {c0[i], c1[i], c2[i]}, 34 | {MOD0, MOD1, MOD2}, 35 | x, 36 | _m); 37 | cout << (int) (x % MOD) << ' '; 38 | } 39 | cout << endl; 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /Math/tests/prime_pi.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/counting_primes" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../Prime/PrimePi.h" 7 | 8 | int32_t main() { 9 | ios::sync_with_stdio(0); cin.tie(0); 10 | long long n; cin >> n; 11 | cout << prime_pi(n) << endl; 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /Math/tests/rabin_miller_32_stress.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_1_A" 2 | 3 | #include "../../template.h" 4 | #include "../Prime/SieveFast.h" 5 | #include "../Prime/RabinMiller32.h" 6 | 7 | bitset all_primes; 8 | void newPrime(int p) { 9 | all_primes[p] = 1; 10 | } 11 | 12 | void solve() { 13 | srand(7777); 14 | sieve(INT_MAX, newPrime); 15 | cerr << "DONE SIEVE" << endl; 16 | for (int i = 0; i < INT_MAX; ++i) { 17 | if (rand() % 30) continue; 18 | if (all_primes[i] == 1) assert(is_prime(i)); 19 | else assert(!is_prime(i)); 20 | } 21 | 22 | cout << "Hello World\n"; 23 | } 24 | -------------------------------------------------------------------------------- /Math/tests/sieve.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/enumerate_primes" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../Prime/Sieve.h" 7 | 8 | int n, a, b, cnt = 0, cnt_mod = 0; 9 | vector ps; 10 | void newPrime(int p) { 11 | if (p > n) { 12 | cout << cnt << ' ' << ps.size() << '\n'; 13 | for (int x : ps) cout << x << ' '; 14 | exit(0); 15 | } 16 | if (cnt_mod == b) ps.push_back(p); 17 | ++cnt; 18 | ++cnt_mod; 19 | if (cnt_mod == a) cnt_mod = 0; 20 | } 21 | 22 | int32_t main() { 23 | cin >> n >> a >> b; 24 | sieve(1'000'000'000, newPrime); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Math/tests/sieve_fast.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/enumerate_primes" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../Prime/SieveFast.h" 7 | 8 | int n, a, b, cnt = 0, cnt_mod = 0; 9 | vector ps; 10 | void newPrime(int p) { 11 | if (p > n) { 12 | cout << cnt << ' ' << ps.size() << '\n'; 13 | for (int x : ps) cout << x << ' '; 14 | exit(0); 15 | } 16 | if (cnt_mod == b) ps.push_back(p); 17 | ++cnt; 18 | ++cnt_mod; 19 | if (cnt_mod == a) cnt_mod = 0; 20 | } 21 | 22 | int32_t main() { 23 | cin >> n >> a >> b; 24 | sieve(1'000'000'000, newPrime); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Math/tests/smallest_prime_factor_stress.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_1_A" 2 | 3 | #include "../../template.h" 4 | #include "../multiplicative_functions_linear.h" 5 | using namespace linear_sieve; 6 | 7 | void solve() { 8 | const int N = 10000; 9 | linear_sieve_smallest_prime_factor(N + 1); 10 | assert(smallest_p[1] == 0); 11 | for (int n = 2; n <= N; ++n) { 12 | bool is_prime = true; 13 | for (int i = 2; i*i <= n; ++i) { 14 | if (n % i == 0) { 15 | is_prime = false; 16 | assert(smallest_p[n] == i); 17 | break; 18 | } 19 | } 20 | if (is_prime) assert(smallest_p[n] == 0); 21 | } 22 | cout << "Hello World\n"; 23 | } 24 | -------------------------------------------------------------------------------- /Math/tests/sqrt_mod.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/sqrt_mod" 2 | 3 | #include 4 | using namespace std; 5 | 6 | // for 64-bit, use mt19937_64 7 | mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); 8 | long long get_rand(long long r) { 9 | return uniform_int_distribution (0, r-1)(rng); 10 | } 11 | 12 | #include "../NumberTheory/SqrtMod.h" 13 | 14 | int32_t main() { 15 | ios::sync_with_stdio(0); cin.tie(0); 16 | int ntest; cin >> ntest; 17 | while (ntest--) { 18 | long long n, p; cin >> n >> p; 19 | long long res = sqrtMod(n, p); 20 | cout << res << '\n'; 21 | } 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Math/tests/sumdiv.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/sum_of_floor_of_linear" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../SumDiv_SumMod.h" 7 | 8 | int32_t main() { 9 | ios::sync_with_stdio(0); cin.tie(0); 10 | int ntest; cin >> ntest; 11 | while (ntest--) { 12 | ll n, m, a, b; cin >> n >> m >> a >> b; 13 | cout << sum_div(b, a, m, n) << '\n'; 14 | } 15 | return 0; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /Math/tests/yosupo_bigint_add.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/addition_of_big_integers" 2 | 3 | #include "bits/stdc++.h" 4 | using namespace std; 5 | 6 | #include "../bigint.h" 7 | 8 | int main() { 9 | ios::sync_with_stdio(0); cin.tie(0); 10 | int ntest; cin >> ntest; 11 | while (ntest--) { 12 | BigInt a, b; cin >> a >> b; 13 | cout << a + b << endl; 14 | } 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /Math/tests/yosupo_primality_rabin_miller.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/primality_test" 2 | 3 | #include "../../template.h" 4 | #include "../Prime/RabinMiller.h" 5 | 6 | void solve() { 7 | int q; cin >> q; 8 | while (q--) { 9 | int64_t n; cin >> n; 10 | cout << (is_prime(n) ? "Yes" : "No") << '\n'; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Misc/Die.cpp: -------------------------------------------------------------------------------- 1 | #include "../template.h" 2 | #include "Die.h" 3 | int main() { 4 | } 5 | -------------------------------------------------------------------------------- /Misc/Die.h: -------------------------------------------------------------------------------- 1 | const int rotations[6][4] = { 2 | {1, 4, 0, 5}, // left 3 | {1, 5, 0, 4}, // right 4 | {4, 3, 5, 2}, // up 5 | {4, 2, 5, 3}, // down 6 | }; 7 | struct Die; 8 | map dieMap; 9 | struct Die { 10 | int arr[6]; /* 0 right, 1 left, 2 forward, 3 backward, 4 top, 5 bottom */ 11 | Die(){ REP(i,6) arr[i] = i; } 12 | Die(int cipher) { // 0 -> 23 13 | if (dieMap.empty()) puts("Call openDie(die());"); else (*this) = dieMap[cipher]; 14 | } 15 | Die move(int dir) { 16 | Die res = (*this); 17 | int t = res.arr[rotations[dir][0]]; 18 | REP(i,3) res.arr[rotations[dir][i]] = res.arr[rotations[dir][i+1]]; 19 | res.arr[rotations[dir][3]] = t; 20 | return res; 21 | } 22 | int encrypt() { // 0 -> 23 23 | int res = arr[0] * 4; 24 | FOR(i,3,5) if (arr[i] < arr[2]) res++; 25 | return res; 26 | } 27 | }; 28 | void openDie(Die t) { 29 | dieMap[t.encrypt()] = t; 30 | REP(dir,4) if (!dieMap.count(t.move(dir).encrypt())) openDie(t.move(dir)); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /Misc/Johnson.txt: -------------------------------------------------------------------------------- 1 | 2 machines: 2 | - Job i: A[i], B[i] 3 | - Sort by min(A[i], B[i]) 4 | - Consider job i (sorted order): 5 | if A[i] <= B[i] --> schedule first 6 | else schedule last 7 | -------------------------------------------------------------------------------- /Misc/KnightMove.h: -------------------------------------------------------------------------------- 1 | // Knight’s shortest path (from (0, 0)) 2 | // Tested: 3 | // - https://open.kattis.com/problems/knightstrip 4 | int KSP(int x, int y) { 5 | if (x < 0) x = -x; 6 | if (y < 0) y = -y; 7 | if (x < y) swap(x, y); 8 | if (x == 1 && y == 0) return 3; 9 | if (x == 2 && y == 2) return 4; 10 | int d = x - y; 11 | if (y > d) return 2 * ((y - d + 2) / 3) + d; 12 | return d - 2 * ((d - y) / 4); 13 | } 14 | -------------------------------------------------------------------------------- /Misc/bitmask_utils.h: -------------------------------------------------------------------------------- 1 | // bitmask utils {{{ 2 | inline uint64_t two(int b) { 3 | return 1ULL << b; 4 | } 5 | inline uint64_t flip_bit(uint64_t mask, int b) { 6 | return mask ^ two(b); 7 | } 8 | inline int get_bit(uint64_t mask, int b) { 9 | return (mask >> b) & 1ULL; 10 | } 11 | inline uint64_t set_bit(uint64_t mask, int b, int new_val) { 12 | return mask + (new_val - get_bit(mask, b)) * two(b); 13 | } 14 | inline int popcount(uint64_t mask) { 15 | return __builtin_popcountll(mask); 16 | } 17 | inline int ctz(uint64_t mask) { 18 | return __builtin_ctzll(mask); 19 | } 20 | template 21 | inline void for_each_submask(uint64_t mask, F f) { 22 | for (uint64_t submask = mask; submask > 0; submask = (submask - 1) & mask) { 23 | f(submask); 24 | } 25 | } 26 | // }}} 27 | -------------------------------------------------------------------------------- /Misc/board_utils.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int n_row, n_col; 5 | 6 | // board utils {{{ 7 | inline int get_id(int r, int c) { 8 | return r * n_col + c; 9 | } 10 | inline std::pair get_rc(int id) { 11 | return std::make_pair(id / n_col, id % n_col); 12 | } 13 | inline bool is_inside(int r, int c) { 14 | return 0 <= r && r < n_row 15 | && 0 <= c && c < n_col; 16 | } 17 | 18 | const std::vector> DIRECTIONS = { 19 | {-1, 0}, {1, 0}, {0, -1}, {0, 1}, 20 | // 8 directions: 21 | // {-1, -1}, {-1, 1}, {1, -1}, {1, 1}, 22 | }; 23 | // }}} 24 | -------------------------------------------------------------------------------- /Misc/input_utils.h: -------------------------------------------------------------------------------- 1 | /// GRAPHS, 1-based index 2 | // undirected graph, N M u1 v1 u2 v2 ... {{{ 3 | int n, m; cin >> n >> m; 4 | vector> g(n); 5 | for (int i = 0; i < m; ++i) { 6 | int u, v; cin >> u >> v; 7 | --u; --v; 8 | g[u].push_back(v); 9 | g[v].push_back(u); 10 | } 11 | // }}} 12 | // directed graph, N M u1 v1 u2 v2 ... {{{ 13 | int n, m; cin >> n >> m; 14 | vector> g(n); 15 | for (int i = 0; i < m; ++i) { 16 | int u, v; cin >> u >> v; 17 | --u; --v; 18 | g[u].push_back(v); 19 | } 20 | // }}} 21 | // tree N u1 v1 u2 v2 ... {{{ 22 | int n; cin >> n; 23 | vector> g(n); 24 | for (int i = 1; i < n; ++i) { 25 | int u, v; cin >> u >> v; 26 | --u; --v; 27 | g[u].push_back(v); 28 | g[v].push_back(u); 29 | } 30 | // }}} 31 | 32 | -------------------------------------------------------------------------------- /Misc/int128.h: -------------------------------------------------------------------------------- 1 | // i128 helper functions {{{ 2 | using i128 = __int128_t; 3 | i128 str2i128(std::string str) { 4 | i128 ret = 0; 5 | bool minus = false; 6 | for (auto c : str) { 7 | if (c == '-') 8 | minus = true; 9 | else 10 | ret = ret * 10 + c - '0'; 11 | } 12 | return minus ? -ret : ret; 13 | } 14 | std::istream &operator>>(std::istream &is, i128 &x) { 15 | std::string s; 16 | return is >> s, x = str2i128(s), is; 17 | } 18 | std::ostream &operator<<(std::ostream &os, const i128 &x) { 19 | i128 tmp = x; 20 | if (tmp == 0) return os << 0; 21 | std::vector ds; 22 | if (tmp < 0) { 23 | os << '-'; 24 | while (tmp) { 25 | int d = tmp % 10; 26 | if (d > 0) d -= 10; 27 | ds.emplace_back(-d), tmp = (tmp - d) / 10; 28 | } 29 | } else { 30 | while (tmp) ds.emplace_back(tmp % 10), tmp /= 10; 31 | } 32 | std::reverse(ds.begin(), ds.end()); 33 | for (auto i : ds) os << i; 34 | return os; 35 | } 36 | i128 my_abs(i128 n) { 37 | if (n < 0) return -n; 38 | return n; 39 | } 40 | i128 gcd(i128 a, i128 b) { 41 | if (b == 0) return a; 42 | return gcd(b, a % b); 43 | } 44 | // Count trailing zeroes 45 | int ctz128(i128 n) { 46 | if (!n) return 128; 47 | 48 | if (!static_cast(n)) { 49 | return __builtin_ctzll(static_cast(n >> 64)) + 64; 50 | } else { 51 | return __builtin_ctzll(static_cast(n)); 52 | } 53 | } 54 | // }}} 55 | 56 | -------------------------------------------------------------------------------- /Misc/left_nearest_smaller.h: -------------------------------------------------------------------------------- 1 | // Nearest smaller {{{ 2 | // Tested: 3 | // - https://cses.fi/problemset/task/1645 4 | // - https://cses.fi/problemset/task/1142 5 | // - https://oj.vnoi.info/problem/kagain 6 | // 7 | // return: 8 | // - left[i] = largest j such that 9 | // j < i 10 | // a[j] < a[i] 11 | // - no such j -> left[i] = -1 12 | vector leftNearestSmaller(const vector& a) { 13 | int n = a.size(); 14 | vector left(n); 15 | stack st; // positions of candidates, A is increasing 16 | st.push(-1); 17 | for (int i = 0; i < n; i++) { 18 | while (st.top() >= 0 && a[st.top()] >= a[i]) st.pop(); 19 | left[i] = st.top(); 20 | st.push(i); 21 | } 22 | return left; 23 | } 24 | 25 | // return: 26 | // - right[i] = smallest j such that: 27 | // j > i 28 | // a[j] < a[i] 29 | // - no such j -> right[i] = n 30 | vector rightNearestSmaller(const vector& a) { 31 | int n = a.size(); 32 | vector right(n); 33 | stack st; // positions of candidates, A is increasing 34 | st.push(n); 35 | for (int i = n-1; i >= 0; i--) { 36 | while (st.top() < n && a[st.top()] >= a[i]) st.pop(); 37 | right[i] = st.top(); 38 | st.push(i); 39 | } 40 | return right; 41 | } 42 | // }}} 43 | -------------------------------------------------------------------------------- /Misc/magic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // Given array D[i] 4 | // Calculate D'[i] = sum( D[j] | j is subset of i ) 5 | void sum_of_subset(std::vector& D, int K) { 6 | for (int i = 0; i < K; ++i) 7 | for (int mask = 0; mask < (1 << K); ++mask) 8 | if ((mask >> i) & 1) D[mask] += D[mask ^ (1 << i)]; 9 | } 10 | 11 | // Given array D[i] 12 | // Calculate D'[i] = sum( D[j] | j is superset of i ) 13 | void sum_of_superset(std::vector& D, int K) { 14 | std::reverse(D.begin(), D.end()); 15 | for (int i = 0; i < K; ++i) 16 | for (int mask = 0; mask < (1 << K); ++mask) 17 | if ((mask >> i) & 1) D[mask] += D[mask ^ (1 << i)]; 18 | std::reverse(D.begin(), D.end()); 19 | } 20 | -------------------------------------------------------------------------------- /Misc/mink.h: -------------------------------------------------------------------------------- 1 | // Tested: 2 | // - 1D: https://oj.vnoi.info/problem/mink 3 | // - 2D (just do 1D twice, for row then for col): https://www.spoj.com/problems/ADASQR/ 4 | // 5 | // NOTE: Must update MN 6 | const int MN = 5000111; 7 | 8 | // Return min of each length-K-subarray for range [left, right) {{{ 9 | template 10 | vector mink(const std::vector& a, int k) { 11 | // deque maintaining candidates in *increasing order* 12 | // Avoid using std::deque because of performance 13 | int head = 0, tail = -1; 14 | static pair buf[MN]; 15 | 16 | auto is_empty = [&] () { return head > tail; }; 17 | auto add = [&] (int id, T val) { 18 | while (!is_empty() && buf[tail].second >= val) --tail; 19 | buf[++tail] = {id, val}; 20 | }; 21 | // remove all ids <= lower_bound 22 | auto rem = [&] (int lower_bound) { 23 | if (!is_empty() && buf[head].first <= lower_bound) ++head; 24 | }; 25 | 26 | int n = a.size(); 27 | vector res(n - k + 1); 28 | for (int i = 0; i < n; ++i) { 29 | add(i, a[i]); 30 | if (i >= k-1) { 31 | rem(i - k); 32 | res[i-k+1] = buf[head].second; 33 | } 34 | } 35 | return res; 36 | } 37 | // }}} 38 | -------------------------------------------------------------------------------- /Misc/number_utils.h: -------------------------------------------------------------------------------- 1 | // return digits of an integer (reversed order) {{{ 2 | vector get_digits(int n) { 3 | if (n == 0) return {0}; 4 | vector res; 5 | while (n > 0) { 6 | res.push_back(n % 10); 7 | n /= 10; 8 | } 9 | return res; 10 | } 11 | // }}} 12 | // reverse an integer {{{ 13 | int reverse(int n) { 14 | int res = 0; 15 | while (n > 0) { 16 | res = res * 10 + n % 10; 17 | n /= 10; 18 | } 19 | return res; 20 | } 21 | // }}} 22 | -------------------------------------------------------------------------------- /Misc/radix_sort_32bit.h: -------------------------------------------------------------------------------- 1 | // Note: Doesn't handle negative numbers 2 | void radix_sort(std::vector& arr) { 3 | const uint32_t FULL_MASK = (1<<16) - 1; 4 | auto get1 = [] (uint32_t x) { return x & FULL_MASK; }; 5 | auto get2 = [] (uint32_t x) { return x >> 16; }; 6 | 7 | std::vector cnt1(1<<16, 0); // frequencies of low bits 8 | std::vector cnt2(1<<16, 0); // frequencies of high bits 9 | for (auto x : arr) { 10 | cnt1[get1(x)]++; 11 | cnt2[get2(x)]++; 12 | } 13 | std::partial_sum(cnt1.begin(), cnt1.end(), cnt1.begin()); 14 | std::partial_sum(cnt2.begin(), cnt2.end(), cnt2.begin()); 15 | 16 | int n = arr.size(); 17 | std::vector tmp(n); 18 | for (int i = n-1; i >= 0; --i) tmp[--cnt1[get1(arr[i])]] = arr[i]; 19 | for (int i = n-1; i >= 0; --i) arr[--cnt2[get2(tmp[i])]] = tmp[i]; 20 | } 21 | -------------------------------------------------------------------------------- /Misc/tests/aizu_dpl_3_b_largest_01_rectangle.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_3_B" 2 | 3 | #include "../../template.h" 4 | #include "../left_nearest_smaller.h" 5 | 6 | long long largestHistogram(const vector& a) { 7 | int n = a.size(); 8 | auto left = leftNearestSmaller(a); 9 | auto right = rightNearestSmaller(a); 10 | 11 | long long res = 0; 12 | for (int i = 0; i < n; i++) { 13 | int l = left[i] + 1; 14 | int r = right[i] - 1; 15 | res = max(res, a[i] * (r - l + 1LL)); 16 | } 17 | return res; 18 | } 19 | 20 | void solve() { 21 | int n_row, n_col; cin >> n_row >> n_col; 22 | vector> a(n_row, vector (n_col)); 23 | for (auto& row : a) { 24 | for (auto& x : row) { 25 | cin >> x; 26 | x = 1 - x; 27 | } 28 | } 29 | 30 | long long res = 0; 31 | for (int r = 0; r < n_row; r++) { 32 | if (r > 0) { 33 | for (int c = 0; c < n_col; c++) { 34 | if (a[r][c]) a[r][c] = a[r-1][c] + 1; 35 | else a[r][c] = 0; 36 | } 37 | } 38 | res = max(res, largestHistogram(a[r])); 39 | } 40 | cout << res << endl; 41 | } 42 | -------------------------------------------------------------------------------- /Misc/tests/aizu_dpl_3_c_largest_histogram.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_3_C" 2 | 3 | #include "../../template.h" 4 | #include "../left_nearest_smaller.h" 5 | 6 | void solve() { 7 | int n; cin >> n; 8 | vector a(n); for(int& x : a) cin >> x; 9 | 10 | auto left = leftNearestSmaller(a); 11 | auto right = rightNearestSmaller(a); 12 | 13 | long long res = 0; 14 | for (int i = 0; i < n; i++) { 15 | int l = left[i] + 1; 16 | int r = right[i] - 1; 17 | res = max(res, a[i] * (r - l + 1LL)); 18 | } 19 | cout << res << endl; 20 | } 21 | -------------------------------------------------------------------------------- /Misc/tests/yosupo_int128.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/many_aplusb_128bit" 2 | 3 | #include "../../template.h" 4 | #include "../int128.h" 5 | 6 | void solve() { 7 | int ntest; cin >> ntest; 8 | while (ntest--) { 9 | i128 a, b; cin >> a >> b; 10 | cout << a+b << '\n'; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Misc/two_pointers.h: -------------------------------------------------------------------------------- 1 | // O(N) 2 pointers 2 | // Find *smallest* substring that satisfy a predicate while minimizing a cost function 3 | // (when not satisfy -> expand -> assume expand is always valid) 4 | // 5 | // - pred() = whether current segment satisfy condition 6 | // - cost(l, r) = cost of [l, r] 7 | // - add(i) = add i to current segment 8 | // - rem(i) = remove i from current segment 9 | // - indices from 0 to n-1 10 | // 11 | // Returns: where [left, right] is substring with 12 | // mincost or [-1, -1] if no solution 13 | // 14 | // Tested: 15 | // - https://www.spoj.com/problems/KOIREP/ 16 | // 17 | // Two pointers (smallest substring) {{{ 18 | template 19 | tuple two_pointers(int n, Pred pred, Cost cost, Add add, Rem rem) { 20 | tuple res {LLONG_MAX, -1, -1}; 21 | 22 | // current window is [l, r] 23 | for (int l = 0, r = -1; l < n; ++l) { 24 | while (r+1 < n && !pred()) { 25 | ++r; 26 | add(r); 27 | } 28 | if (pred()) { 29 | res = min(res, {cost(l, r), l, r}); 30 | } 31 | rem(l); 32 | } 33 | return res; 34 | } 35 | // }}} 36 | -------------------------------------------------------------------------------- /Misc/vec_utils.h: -------------------------------------------------------------------------------- 1 | // Vec utils {{{ 2 | // Given vector `a`, commpute next[i] = position of next occurrence of a[i] 3 | // Returns -1 if no next occurrence 4 | template 5 | std::vector getNext(const Container& a) { 6 | std::map cur; 7 | std::vector res(a.size()); 8 | int n = a.size(); 9 | 10 | for (int i = n - 1; i >= 0; --i) { 11 | res[i] = cur.count(a[i]) ? cur[a[i]] : -1; 12 | cur[a[i]] = i; 13 | } 14 | 15 | return res; 16 | } 17 | // Given vector `a`, commpute prev[i] = position of previous occurrence of a[i] 18 | // Returns -1 if no previous occurrence 19 | template 20 | std::vector getPrev(const Container& a) { 21 | std::map cur; 22 | std::vector res(a.size()); 23 | int n = a.size(); 24 | 25 | for (int i = 0; i < n; ++i) { 26 | res[i] = cur.count(a[i]) ? cur[a[i]] : -1; 27 | cur[a[i]] = i; 28 | } 29 | 30 | return res; 31 | } 32 | // }}} 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # C++ Algorithm library for Competitive programming 2 | 3 | [![Actions Status](https://github.com/ngthanhtrung23/ACM_Notebook_New/workflows/verify/badge.svg)](https://github.com/ngthanhtrung23/ACM_Notebook_New/actions) 4 | 5 | [Documentation](https://ngthanhtrung23.github.io/ACM_Notebook_new/) 6 | 7 | Initially, I created this for my ICPC team's notebook for season 2015-2016. 8 | Most of the code has evolved since then. 9 | -------------------------------------------------------------------------------- /String/.gitignore: -------------------------------------------------------------------------------- 1 | lyndon 2 | minmove 3 | manacher 4 | zfunc 5 | SuffixArray 6 | -------------------------------------------------------------------------------- /String/kmp.h: -------------------------------------------------------------------------------- 1 | // prefix function: *length* of longest prefix which is also suffix: 2 | // pi[i] = max(k: s[0..k-1] == s[i-(k-1)..i] 3 | // 4 | // KMP {{{ 5 | template 6 | std::vector prefix_function(const Container& s) { 7 | int n = s.size(); 8 | std::vector pi(n); 9 | for (int i = 1; i < n; ++i) { 10 | int j = pi[i-1]; 11 | while (j > 0 && s[i] != s[j]) j = pi[j-1]; 12 | if (s[i] == s[j]) ++j; 13 | pi[i] = j; 14 | } 15 | return pi; 16 | } 17 | 18 | // Tested: https://oj.vnoi.info/problem/substr 19 | // Return all positions (0-based) that pattern `pat` appears in `text` 20 | std::vector kmp(const std::string& pat, const std::string& text) { 21 | auto pi = prefix_function(pat + '\0' + text); 22 | std::vector res; 23 | for (size_t i = pi.size() - text.size(); i < pi.size(); ++i) { 24 | if (pi[i] == (int) pat.size()) { 25 | res.push_back(i - 2 * pat.size()); 26 | } 27 | } 28 | return res; 29 | } 30 | 31 | // Tested: https://oj.vnoi.info/problem/icpc22_mt_b 32 | // Returns cnt[i] = # occurrences of prefix of length-i 33 | // NOTE: cnt[0] = n+1 (0-length prefix appears n+1 times) 34 | std::vector prefix_occurrences(const string& s) { 35 | int n = s.size(); 36 | auto pi = prefix_function(s); 37 | std::vector res(n + 1); 38 | for (int i = 0; i < n; ++i) res[pi[i]]++; 39 | for (int i = n-1; i > 0; --i) res[pi[i-1]] += res[i]; 40 | for (int i = 0; i <= n; ++i) res[i]++; 41 | return res; 42 | } 43 | // }}} 44 | -------------------------------------------------------------------------------- /String/lyndon.cpp: -------------------------------------------------------------------------------- 1 | #include "../template.h" 2 | #include "lyndon.h" 3 | 4 | int main() { 5 | lyndon("abcdef"); // abcdef 6 | lyndon("fedcba"); // f e d c b a 7 | lyndon("aaaaaa"); // a a a a a a 8 | lyndon("ababab"); // ab ab ab 9 | } 10 | -------------------------------------------------------------------------------- /String/lyndon.h: -------------------------------------------------------------------------------- 1 | // Decompose s = w1w2..wk : k max and w1 >= w2 >= ... 2 | // each wi is strictly smaller than all its rotation 3 | void lyndon(string s) { 4 | int n = (int) s.length(); 5 | int i = 0; 6 | while (i < n) { 7 | int j = i + 1, k = i; 8 | while (j < n && s[k] <= s[j]) { 9 | if (s[k] < s[j]) k = i; 10 | else ++k; 11 | ++j; 12 | } 13 | while (i <= k) { 14 | cout << s.substr(i, j - k) << ' '; 15 | i += j - k; 16 | } 17 | } 18 | cout << endl; 19 | } 20 | -------------------------------------------------------------------------------- /String/manacher.h: -------------------------------------------------------------------------------- 1 | // Manacher {{{ 2 | // Return 3 | // - even_len[i] = length of longest palindrome centered at [i, i+1] 4 | // - odd_len[i] = length of longest palindrome centered at i 5 | // 6 | // Tested: 7 | // - https://judge.yosupo.jp/problem/enumerate_palindromes 8 | // - https://oj.vnoi.info/problem/paliny 9 | std::array, 2> manacher(const string& s) { 10 | int n = s.size(); 11 | std::array res = {vector (n+1, 0), vector (n, 0)}; 12 | 13 | for (int z = 0; z < 2; z++) { 14 | for (int i = 0, l = 0, r = 0; i < n; i++) { 15 | int t = r - i + !z; 16 | if (i < r) res[z][i] = min(t, res[z][l + t]); 17 | 18 | int l2 = i - res[z][i], r2 = i + res[z][i] - !z; 19 | while (l2 && r2 + 1 < n && s[l2 - 1] == s[r2 + 1]) { 20 | ++res[z][i]; 21 | --l2; 22 | ++r2; 23 | } 24 | if (r2 > r) { 25 | l = l2; 26 | r = r2; 27 | } 28 | } 29 | for (int i = 0; i < n; i++) { 30 | res[z][i] = 2*res[z][i] + z; 31 | } 32 | } 33 | res[0].erase(res[0].begin(), res[0].begin() + 1); 34 | res[0].pop_back(); 35 | return res; 36 | } 37 | // }}} 38 | -------------------------------------------------------------------------------- /String/minmove.cpp: -------------------------------------------------------------------------------- 1 | #include "../template.h" 2 | #include "minmove.h" 3 | 4 | int main() { 5 | cout << minmove("mississippi") << endl; // 10 6 | cout << minmove("cdefab") << endl; // 4 7 | cout << minmove("zzzzzz") << endl; // 0 8 | } 9 | -------------------------------------------------------------------------------- /String/minmove.h: -------------------------------------------------------------------------------- 1 | // Tính vị trí của xâu xoay vòng có thứ tự từ điển nhỏ nhất của xâu s[] 2 | // Tested: 3 | // - https://cses.fi/problemset/task/1110/ 4 | int minmove(string s) { 5 | int n = s.length(); 6 | int x, y, i, j, u, v; // x is the smallest string before string y 7 | for (x = 0, y = 1; y < n; ++ y) { 8 | i = u = x; 9 | j = v = y; 10 | while (s[i] == s[j]) { 11 | ++ u; ++ v; 12 | if (++ i == n) i = 0; 13 | if (++ j == n) j = 0; 14 | if (i == x) break; // All strings are equal 15 | } 16 | if (s[i] <= s[j]) y = v; 17 | else { 18 | x = y; 19 | if (u > y) y = u; 20 | } 21 | } 22 | return x; 23 | } 24 | -------------------------------------------------------------------------------- /String/tests/aizu_alds_14_b_string_hash.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_14_B" 2 | 3 | #include "../../template.h" 4 | #include "../hash.h" 5 | #define SZ(x) ((int)(x).size()) 6 | 7 | HashGenerator g(1000111); 8 | void solve() { 9 | std::string a, b; std::cin >> a >> b; 10 | 11 | auto hb = g.hash(b); 12 | auto ha = g.hash(a); 13 | 14 | for (int i = 0; i + SZ(b) <= SZ(a); i++) { 15 | if (g.equals(hb, 0, SZ(b) - 1, 16 | ha, i, i + SZ(b) - 1)) { 17 | std::cout << i << '\n'; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /String/tests/lcp.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/number_of_substrings" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../SuffixArray.h" 7 | 8 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 9 | #define SZ(x) ((int)(x).size()) 10 | 11 | int32_t main() { 12 | ios::sync_with_stdio(0); cin.tie(0); 13 | string s; cin >> s; 14 | cout << cnt_distinct_substrings(s) << endl; 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /String/tests/manacher.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/enumerate_palindromes" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../manacher.h" 7 | 8 | #define REP(i, a) for (int i = 0, _##i = (a); i < _##i; ++i) 9 | #define SZ(x) ((int)(x).size()) 10 | 11 | int32_t main() { 12 | ios::sync_with_stdio(0); cin.tie(0); 13 | string s; cin >> s; 14 | auto [even, odd] = manacher(s); 15 | 16 | REP(i,SZ(s)) { 17 | cout << odd[i] << ' '; 18 | if (i+1 < SZ(s)) cout << even[i] << ' '; 19 | } 20 | cout << endl; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /String/tests/suffix_array.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/suffixarray" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../SuffixArray.h" 7 | 8 | int32_t main() { 9 | ios::sync_with_stdio(0); cin.tie(0); 10 | string s; cin >> s; 11 | auto sa = suffix_array(s, 'a', 'z'); 12 | for (int x : sa) std::cout << x << ' '; 13 | cout << endl; 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /String/tests/suffix_array_queries.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_14_D" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../SuffixArray.h" 7 | 8 | int main() { 9 | ios::sync_with_stdio(0); cin.tie(0); 10 | string s, pat; 11 | int q; 12 | cin >> s >> q; 13 | auto sa = suffix_array(s, 0, 255); 14 | while (q--) { 15 | cin >> pat; 16 | int cnt = cnt_occurrences(s, sa, pat); 17 | cout << (cnt ? 1 : 0) << '\n'; 18 | } 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /String/tests/yukicoder_1408_string_hash_lcp.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://yukicoder.me/problems/1408" 2 | 3 | #include "../../template.h" 4 | #include "../hash.h" 5 | #define SZ(x) ((int)(x).size()) 6 | 7 | HashGenerator g(1000111); 8 | void solve() { 9 | int n; std::cin >> n; 10 | 11 | std::vector> hs; 12 | for (int i = 0; i < n; i++) { 13 | std::string s; std::cin >> s; 14 | 15 | hs.push_back(g.hash(s)); 16 | } 17 | 18 | int m; 19 | long long x, d, res = 0; 20 | std::cin >> m >> x >> d; 21 | 22 | while (m--) { 23 | int i = x / (n - 1); 24 | int j = x % (n - 1); 25 | if (i <= j) ++j; 26 | x = (x + d) % (n * (n-1LL)); 27 | 28 | res += g.maxCommonPrefix( 29 | hs[i], 0, SZ(hs[i]) - 1, 30 | hs[j], 0, SZ(hs[j]) - 1); 31 | } 32 | std::cout << res << '\n'; 33 | } 34 | -------------------------------------------------------------------------------- /String/tests/zfunc.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/zalgorithm" 2 | 3 | #include 4 | using namespace std; 5 | 6 | #include "../zfunc.h" 7 | 8 | int32_t main() { 9 | ios::sync_with_stdio(0); cin.tie(0); 10 | string s; cin >> s; 11 | for (auto x : zfunc(s)) { 12 | cout << x << ' '; 13 | } 14 | cout << '\n'; 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /String/tests/zfunc_hash.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/zalgorithm" 2 | 3 | #include "../../template.h" 4 | #include "../hash.h" 5 | 6 | void solve() { 7 | HashGenerator g(500111); 8 | string s; cin >> s; 9 | auto h = g.hash(s); 10 | 11 | int n = s.size(); 12 | REP(i,n) { 13 | cout << g.maxCommonPrefix(h, 0, n-1, h, i, n-1) << ' '; 14 | } 15 | cout << endl; 16 | } 17 | -------------------------------------------------------------------------------- /String/zfunc.h: -------------------------------------------------------------------------------- 1 | // z[i] = length of longest common prefix of s[0..N] and s[i..N] 2 | // 3 | // Tested: 4 | // - https://judge.yosupo.jp/problem/zalgorithm 5 | // - (string matching) https://oj.vnoi.info/problem/substr 6 | // Z-func {{{ 7 | vector zfunc(const string& s) { 8 | int n = (int) s.length(); 9 | vector z(n); 10 | z[0] = n; 11 | for (int i = 1, l = 0, r = 0; i < n; ++i) { 12 | if (i <= r) 13 | z[i] = min(r - i + 1, z[i - l]); 14 | while (i + z[i] < n && s[z[i]] == s[i + z[i]]) 15 | ++z[i]; 16 | if (i + z[i] - 1 > r) 17 | l = i, r = i + z[i] - 1; 18 | } 19 | return z; 20 | } 21 | // }}} 22 | 23 | // Examples: 24 | // Find all occurrences of p in t 25 | 26 | /** 27 | string s = p + "_" + t; 28 | auto z = zfunc(s); 29 | 30 | REP(i,SZ(t)) { 31 | if (z[i + SZ(p) + 1] == SZ(p)) { 32 | cout << 1+i << ' '; 33 | } 34 | } 35 | cout << endl; 36 | */ 37 | -------------------------------------------------------------------------------- /buffered_reader.h: -------------------------------------------------------------------------------- 1 | // Buffered reader {{{ 2 | namespace IO { 3 | const int BUFSIZE = 1<<14; 4 | char buf[BUFSIZE + 1], *inp = buf; 5 | 6 | bool reacheof; 7 | char get_char() { 8 | if (!*inp && !reacheof) { 9 | memset(buf, 0, sizeof buf); 10 | int tmp = fread(buf, 1, BUFSIZE, stdin); 11 | if (tmp != BUFSIZE) reacheof = true; 12 | inp = buf; 13 | } 14 | return *inp++; 15 | } 16 | template 17 | T get() { 18 | int neg = 0; 19 | T res = 0; 20 | char c = get_char(); 21 | while (!std::isdigit(c) && c != '-' && c != '+') c = get_char(); 22 | if (c == '+') { neg = 0; } 23 | else if (c == '-') { neg = 1; } 24 | else res = c - '0'; 25 | 26 | c = get_char(); 27 | while (std::isdigit(c)) { 28 | res = res * 10 + (c - '0'); 29 | c = get_char(); 30 | } 31 | return neg ? -res : res; 32 | } 33 | }; 34 | // Helper methods 35 | int ri() { 36 | return IO::get(); 37 | } 38 | // }}} 39 | -------------------------------------------------------------------------------- /stack_increase.cpp: -------------------------------------------------------------------------------- 1 | // Source: https://codeforces.com/blog/entry/120772 2 | #include 3 | using namespace std; 4 | void main_() { 5 | // implement your solution here 6 | } 7 | static void run_with_stack_size(void (*func)(void), size_t stsize) { 8 | char *stack, *send; 9 | stack = (char *)malloc(stsize); 10 | send = stack + stsize - 16; 11 | send = (char *)((uintptr_t)send / 16 * 16); 12 | asm volatile( 13 | "mov %%rsp, (%0)\n" 14 | "mov %0, %%rsp\n" 15 | : 16 | : "r"(send)); 17 | func(); 18 | asm volatile("mov (%0), %%rsp\n" : : "r"(send)); 19 | free(stack); 20 | } 21 | int main() { 22 | run_with_stack_size(main_, 1024 * 1024 * 1024); // run with a 1 GiB stack 23 | return 0; 24 | } 25 | --------------------------------------------------------------------------------