├── .github └── workflows │ └── verify.yml ├── .gitignore ├── .verify-helper ├── config.toml ├── docs │ ├── _config.yml │ ├── index.md │ └── static │ │ └── assets │ │ └── js │ │ └── copy-button.js └── timestamps.remote.json ├── README.md ├── convolution ├── arbitrary_mod_convolution.hpp ├── convex_min_plus_convolution.hpp ├── divisor_zeta_moebius_transform.hpp ├── fft.hpp ├── gcd_lcm_convolution.hpp ├── ntt.hpp ├── relaxed_convolution.hpp ├── walsh_hadamard_transform.hpp └── xor_convolution.hpp ├── data-structure ├── binary_trie.hpp ├── bit_vector.hpp ├── bst │ ├── lazy_treap.hpp │ ├── rbst.hpp │ ├── red_black_tree.hpp │ ├── splay_tree.hpp │ └── treap.hpp ├── cht │ ├── convex_hull_trick.hpp │ ├── convex_hull_trick_binsearchtree.hpp │ ├── li_chao_tree.hpp │ ├── nonlinear_convex_hull_trick.hpp │ ├── offline_deletable_convex_hull_trick.hpp │ └── undoable_li_chao_tree.hpp ├── disjoint_sparse_table.hpp ├── fenwick_tree.hpp ├── fenwick_tree_2d.hpp ├── foldable_deque.hpp ├── inner_product_search.hpp ├── kd_tree.hpp ├── leftist_heap.hpp ├── min_max_heap.hpp ├── partition_refinement.hpp ├── persistent_array.hpp ├── persistent_queue.hpp ├── persistent_stack.hpp ├── quadtree.hpp ├── range_fenwick_tree.hpp ├── range_tree.hpp ├── segtree │ ├── dual_segment_tree.hpp │ ├── dual_segment_tree_2d.hpp │ ├── dynamic_lazy_segment_tree.hpp │ ├── dynamic_segment_tree.hpp │ ├── lazy_segment_tree.hpp │ ├── persistent_segment_tree.hpp │ ├── segment_tree.hpp │ ├── segment_tree_2d.hpp │ ├── segment_tree_beats.hpp │ ├── sortable_segment_tree.hpp │ └── xor_segment_tree.hpp ├── slide_min.hpp ├── sliding_window_aggregation.hpp ├── slope_trick.hpp ├── sparse_table.hpp ├── sqrt_tree.hpp ├── unionfind │ ├── partially_persistent_union_find.hpp │ ├── persistent_union_find.hpp │ ├── static_range_union_find.hpp │ ├── undoable_union_find.hpp │ ├── union_find.hpp │ └── weighted_union_find.hpp └── wavelet_matrix.hpp ├── docs ├── convolution │ ├── arbitrary_mod_convolution.md │ ├── convex_min_plus_convolution.md │ ├── divisor_zeta_moebius_transform.md │ ├── fft.md │ ├── ntt.md │ ├── relaxed_convolution.md │ └── walsh_hadamard_transform.md ├── data-structure │ ├── binary_trie.md │ ├── bit_vector.md │ ├── bst │ │ ├── lazy_treap.md │ │ ├── rbst.md │ │ ├── splay_tree.md │ │ └── treap.md │ ├── cht │ │ ├── convex_hull_trick.md │ │ ├── convex_hull_trick_binsearchtree.md │ │ ├── li_chao_tree.md │ │ ├── nonlinear_convex_hull_trick.md │ │ └── offline_deletable_convex_hull_trick.md │ ├── disjoint_sparse_table.md │ ├── fenwick_tree.md │ ├── foldable_deque.md │ ├── kd_tree.md │ ├── leftist_heap.md │ ├── min_max_heap.md │ ├── partition_refinement.md │ ├── persistent_array.md │ ├── persistent_queue.md │ ├── persistent_stack.md │ ├── quadtree.md │ ├── range_fenwick_tree.md │ ├── range_tree.md │ ├── segtree │ │ ├── dual_segment_tree.md │ │ ├── dynamic_segment_tree.md │ │ ├── lazy_segment_tree.md │ │ ├── segment_tree.md │ │ ├── segment_tree_2d.md │ │ ├── segment_tree_beats.md │ │ ├── sortable_segment_tree.md │ │ └── xor_segment_tree.md │ ├── slide_min.md │ ├── sliding_window_aggregation.md │ ├── slope_trick.md │ ├── sparse_table.md │ ├── sqrt_tree.md │ ├── unionfind │ │ ├── partially_persistent_union_find.md │ │ ├── persistent_union_find.md │ │ ├── static_range_union_find.md │ │ ├── undoable_union_find.md │ │ ├── union_find.md │ │ └── weighted_union_find.md │ └── wavelet_matrix.md ├── dp │ ├── hu_tucker.md │ ├── monge_shortest_path.md │ ├── monotone_minima.md │ └── smawk.md ├── flow │ ├── dinic.md │ ├── dm_decomposition.md │ ├── ford_fulkerson.md │ ├── min_cost_b_flow.md │ └── min_cost_flow.md ├── geometry │ ├── convex_hull.md │ ├── delaunay_diagram.md │ ├── geometry.md │ └── minimum_bounding_circle.md ├── graph │ ├── assignment.md │ ├── biconnected_components.md │ ├── bipartite_edge_coloring.md │ ├── bipartite_matching.md │ ├── chordal_graph_recognition.md │ ├── chromatic_number.md │ ├── complement_bfs.md │ ├── dominator_tree.md │ ├── enumerate_cliques.md │ ├── enumerate_triangles.md │ ├── eulerian_walk.md │ ├── general_matching.md │ ├── junction_tree.md │ ├── lex_bfs.md │ ├── lowlink.md │ ├── manhattan_mst.md │ ├── maximum_independent_set.md │ ├── maximum_weight_independent_set.md │ ├── minimum_steiner_tree.md │ ├── mst.md │ ├── offline_dynamic_connectivity.md │ ├── range_edge_graph.md │ ├── scc.md │ ├── shortest_path.md │ ├── topological_sort.md │ └── two_edge_connected_components.md ├── math │ ├── berlekamp_massey.md │ ├── bernoulli.md │ ├── bostan_mori.md │ ├── combination.md │ ├── combination_arbitrary_mod.md │ ├── convert_base.md │ ├── count_subset_sum.md │ ├── factorial.md │ ├── interpolation.md │ ├── kitamasa.md │ ├── lagrange_interpolation.md │ ├── lagrange_polynomial.md │ ├── linalg │ │ ├── characteristic_polynomial.md │ │ ├── hafnian.md │ │ ├── matrix.md │ │ └── system_of_linear_equations.md │ ├── multipoint_evaluation.md │ ├── nimber.md │ ├── number-theory │ │ ├── carmichael.md │ │ ├── divisor.md │ │ ├── euler_totient.md │ │ ├── extgcd.md │ │ ├── fast_prime.md │ │ ├── floor_sum.md │ │ ├── garner.md │ │ ├── mod_arithmetic.md │ │ ├── moebius.md │ │ ├── prime.md │ │ ├── prime_count.md │ │ ├── primitive_root.md │ │ └── stern_brocot_tree.md │ ├── partition_function.md │ ├── polynomial.md │ ├── q_analogs.md │ ├── set │ │ ├── subset_convolution.md │ │ └── zeta_moebius_transform.md │ ├── stirling_first.md │ └── stirling_second.md ├── misc │ ├── discrete_log_monoid_action.md │ ├── interval_set.md │ ├── intervals.md │ ├── majority.md │ ├── matroid_intersection.md │ ├── memo.md │ ├── mo.md │ ├── sorting.md │ └── stable_matching.md ├── sat │ ├── hornsat.md │ └── twosat.md ├── string │ ├── aho_corasick.md │ ├── enumerate_runs.md │ ├── kmp.md │ ├── lcp_array.md │ ├── lyndon_factorization.md │ ├── manacher.md │ ├── palindromic_tree.md │ ├── pattern_search_2d.md │ ├── rolling_hash.md │ ├── suffix_array.md │ ├── trie.md │ └── z_array.md └── tree │ ├── auxiliary_tree.md │ ├── cartesian_tree.md │ ├── centroid_decomposition.md │ ├── euler_tour_tree.md │ ├── hld.md │ ├── lca.md │ ├── link_cut_tree.md │ ├── permutation_tree.md │ ├── range_contour_aggregation.md │ ├── rerooting.md │ ├── tree_diameter.md │ └── tree_isomorphism.md ├── dp ├── edit_distance.hpp ├── hu_tucker.hpp ├── largest_rectangle.hpp ├── lcs.hpp ├── lis.hpp ├── monge_shortest_path.hpp ├── monotone_minima.hpp └── smawk.hpp ├── flow ├── dinic.hpp ├── ford_fulkerson.hpp ├── min_cost_b_flow.hpp └── min_cost_flow.hpp ├── geometry ├── bisector.hpp ├── closest_pair.hpp ├── convex_hull.hpp ├── delaunay_diagram.hpp ├── dist.hpp ├── furthest_pair.hpp ├── geometry.hpp ├── geometry3d.hpp ├── intersect.hpp ├── intersection.hpp ├── minimum_bounding_circle.hpp ├── polygon.hpp ├── tangent.hpp └── triangle.hpp ├── graph ├── assignment.hpp ├── biconnected_components.hpp ├── bipartite_edge_coloring.hpp ├── bipartite_matching.hpp ├── chordal_graph_recognition.hpp ├── chromatic_number.hpp ├── complement_bfs.hpp ├── dm_decomposition.hpp ├── dominator_tree.hpp ├── enumerate_cliques.hpp ├── enumerate_triangles.hpp ├── eulerian_walk.hpp ├── general_matching.hpp ├── junction_tree.hpp ├── lex_bfs.hpp ├── lowlink.hpp ├── manhattan_mst.hpp ├── maximum_independent_set.hpp ├── maximum_weight_independent_set.hpp ├── minimum_spanning_arborescence.hpp ├── minimum_steiner_tree.hpp ├── mst.hpp ├── offline_dynamic_connectivity.hpp ├── pseudotree_cycle.hpp ├── range_edge_graph.hpp ├── scc.hpp ├── shortest_path.hpp ├── topological_sort.hpp └── two_edge_connected_components.hpp ├── icpc-document ├── .gitignore ├── README.md ├── antbook.tex ├── convolution.tex ├── data-structure.tex ├── file_list.py ├── flow.tex ├── generate.py ├── geometry.tex ├── graph.tex ├── main.markdown.in ├── main.markdown.lua ├── main.pdf ├── main.tex ├── math.tex ├── misc.tex ├── preamble.tex ├── sat.tex ├── string.tex ├── template.tex ├── template │ ├── main.tex │ └── section.tex └── tree.tex ├── math ├── arbitrary_modint.hpp ├── berlekamp_massey.cpp ├── bernoulli.hpp ├── bostan_mori.hpp ├── combination.cpp ├── combination_arbitrary_mod.hpp ├── combination_large.hpp ├── convert_base.cpp ├── count_subset_sum.hpp ├── factorial.hpp ├── gaussian_integer.hpp ├── interpolation.cpp ├── kitamasa.cpp ├── lagrange_interpolation.hpp ├── lagrange_polynomial.hpp ├── linalg │ ├── binary_matrix.hpp │ ├── characteristic_polynomial.hpp │ ├── hafnian.hpp │ ├── matrix.hpp │ └── system_of_linear_equations.hpp ├── modint.hpp ├── montmort.cpp ├── multipoint_evaluation.cpp ├── nimber.hpp ├── number-theory │ ├── carmichael.hpp │ ├── divisor.hpp │ ├── euler_totient.hpp │ ├── extgcd.hpp │ ├── farey_sequence.hpp │ ├── fast_prime.hpp │ ├── floor_sum.hpp │ ├── garner.hpp │ ├── isqrt.hpp │ ├── kth_root.hpp │ ├── mod_arithmetic.hpp │ ├── moebius.hpp │ ├── prime.hpp │ ├── prime_count.hpp │ ├── primitive_root.hpp │ ├── quotients.hpp │ └── stern_brocot_tree.hpp ├── partition_function.hpp ├── polynomial.cpp ├── product_of_polynomial_sequence.hpp ├── q_analogs.hpp ├── set │ ├── and_or_convolution.hpp │ ├── set_power_series.hpp │ ├── subset_convolution.hpp │ └── zeta_moebius_transform.hpp ├── stirling_first.hpp └── stirling_second.hpp ├── misc ├── compress.hpp ├── die.hpp ├── discrete_log_monoid_action.hpp ├── enumerate_subsets.hpp ├── fraction.hpp ├── golden_section_search.hpp ├── interval_set.hpp ├── intervals.hpp ├── majority.hpp ├── marathon_template.cpp ├── matroid_intersection.hpp ├── median_set.hpp ├── memo.hpp ├── min_periodic_function.hpp ├── mo.hpp ├── monoids.cpp ├── permutation.hpp ├── random.hpp ├── rectangle_union.hpp ├── sorting.hpp ├── stable_matching.hpp ├── sum_top_k.hpp └── timer.hpp ├── sat ├── hornsat.hpp └── twosat.hpp ├── string ├── aho_corasick.hpp ├── enumerate_runs.hpp ├── kmp.hpp ├── lcp_array.hpp ├── longest_common_substring.hpp ├── lyndon_factorization.hpp ├── manacher.hpp ├── min_cyclic_shift.hpp ├── palindromic_tree.hpp ├── pattern_search_2d.hpp ├── rolling_hash.hpp ├── suffix_array.hpp ├── trie.hpp └── z_array.hpp ├── test ├── aoj │ ├── 1040.test.cpp │ ├── 1208.test.cpp │ ├── 1283.test.cpp │ ├── 1298.test.cpp │ ├── 1508.rbst.test.cpp │ ├── 1508.splay_tree.test.cpp │ ├── 1508.treap.test.cpp │ ├── 2292.test.cpp │ ├── 2415.test.cpp │ ├── ALDS1_14_B.kmp.test.cpp │ ├── ALDS1_14_B.rolling_hash.test.cpp │ ├── ALDS1_14_C.test.cpp │ ├── ALDS1_1_C.is_prime.test.cpp │ ├── CGL_1_A.test.cpp │ ├── CGL_1_B.test.cpp │ ├── CGL_1_C.test.cpp │ ├── CGL_2_A.test.cpp │ ├── CGL_2_B.test.cpp │ ├── CGL_2_C.test.cpp │ ├── CGL_2_D.test.cpp │ ├── CGL_3_A.test.cpp │ ├── CGL_3_B.test.cpp │ ├── CGL_3_C.test.cpp │ ├── CGL_4_A.test.cpp │ ├── CGL_4_B.test.cpp │ ├── CGL_4_C.test.cpp │ ├── CGL_5_A.test.cpp │ ├── CGL_7_A.test.cpp │ ├── CGL_7_B.test.cpp │ ├── CGL_7_C.test.cpp │ ├── CGL_7_D.test.cpp │ ├── CGL_7_E.test.cpp │ ├── CGL_7_F.test.cpp │ ├── CGL_7_G.test.cpp │ ├── CGL_7_I.test.cpp │ ├── DPL_3_C.test.cpp │ ├── DSL_1_B.test.cpp │ ├── DSL_2_B.dynamic_segment_tree.test.cpp │ ├── DSL_2_B.test.cpp │ ├── DSL_2_C.test.cpp │ ├── DSL_2_F.dynamic_lazy_segment_tree.test.cpp │ ├── DSL_2_G.range_fenwick_tree.test.cpp │ ├── DSL_3_D.slide_min.test.cpp │ ├── DSL_3_D.sparse_table.test.cpp │ ├── GRL_1_A.test.cpp │ ├── GRL_1_B.test.cpp │ ├── GRL_1_C.test.cpp │ ├── GRL_2_A.boruvka.test.cpp │ ├── GRL_2_A.kruskal.test.cpp │ ├── GRL_2_A.prim.test.cpp │ ├── GRL_3_A.test.cpp │ ├── GRL_3_B.test.cpp │ ├── GRL_6_A.dinic.test.cpp │ ├── GRL_6_A.ford_fulkerson.test.cpp │ ├── GRL_6_B.test.cpp │ ├── GRL_7_A.test.cpp │ ├── NTL_1_A.test.cpp │ ├── NTL_1_B.test.cpp │ └── NTL_1_D.test.cpp └── yosupo │ ├── area_of_union_of_rectangles.test.cpp │ ├── assignment.test.cpp │ ├── bernoulli_number.test.cpp │ ├── biconnected_components.test.cpp │ ├── binomial_coefficient_prime_mod.test.cpp │ ├── bipartite_edge_coloring.test.cpp │ ├── bipartitematching.test.cpp │ ├── bitwise_and_convolution.test.cpp │ ├── bitwise_xor_convolution.test.cpp │ ├── cartesian_tree.test.cpp │ ├── characteristic_polynomial.test.cpp │ ├── chordal_graph_recognition.test.cpp │ ├── chromatic_number.test.cpp │ ├── closest_pair.test.cpp │ ├── common_interval_decomposition_tree.test.cpp │ ├── convolution_mod.test.cpp │ ├── convolution_mod_1000000007.test.cpp │ ├── counting_primes.test.cpp │ ├── deque_operate_all_composite.test.cpp │ ├── directedmst.test.cpp │ ├── discrete_logarithm_mod.test.cpp │ ├── division_of_polynomials.test.cpp │ ├── dominatortree.test.cpp │ ├── double_ended_priority_queue.test.cpp │ ├── dynamic_graph_vertex_add_component_sum.test.cpp │ ├── dynamic_sequence_range_affine_range_sum.treap.test.cpp │ ├── dynamic_tree_subtree_add_subtree_sum.test.cpp │ ├── dynamic_tree_vertex_add_subtree_sum.test.cpp │ ├── dynamic_tree_vertex_set_path_composite.test.cpp │ ├── enumerate_cliques.test.cpp │ ├── enumerate_palindromes.test.cpp │ ├── enumerate_primes.test.cpp │ ├── enumerate_quotients.test.cpp │ ├── enumerate_triangles.test.cpp │ ├── exp_of_formal_power_series.test.cpp │ ├── exp_of_set_power_series.test.cpp │ ├── factorial.test.cpp │ ├── factorize.test.cpp │ ├── find_linear_recurrence.test.cpp │ ├── frequency_table_of_tree_distance.test.cpp │ ├── furthest_pair.test.cpp │ ├── gcd_convolution.test.cpp │ ├── gcd_of_gaussian_integers.test.cpp │ ├── general_matching.test.cpp │ ├── hafnian_of_matrix.test.cpp │ ├── inv_of_formal_power_series.test.cpp │ ├── inverse_matrix.test.cpp │ ├── jump_on_tree.test.cpp │ ├── kth_root_integer.test.cpp │ ├── kth_term_of_linearly_recurrent_sequence.test.cpp │ ├── lca.test.cpp │ ├── lcm_convolution.test.cpp │ ├── line_add_get_min.cht.test.cpp │ ├── line_add_get_min.lct.test.cpp │ ├── log_of_formal_power_series.test.cpp │ ├── longest_common_substring.test.cpp │ ├── longest_increasing_subsequence.test.cpp │ ├── lyndon_factorization.test.cpp │ ├── manhattanmst.test.cpp │ ├── matrix_det.test.cpp │ ├── matrix_product.test.cpp │ ├── matrix_product_mod_2.test.cpp │ ├── matrix_rank.test.cpp │ ├── maximum_independent_set.test.cpp │ ├── min_cost_b_flow.test.cpp │ ├── min_plus_convolution_convex_arbitrary.test.cpp │ ├── montmort_number_mod.test.cpp │ ├── multipoint_evaluation.test.cpp │ ├── nim_product_64.test.cpp │ ├── number_of_subsequences.test.cpp │ ├── number_of_substrings.test.cpp │ ├── partition_function.test.cpp │ ├── persistent_queue.test.cpp │ ├── persistent_unionfind.test.cpp │ ├── point_add_rectangle_sum.2d_segtree.test.cpp │ ├── point_add_rectangle_sum.quadtree.test.cpp │ ├── point_set_range_composite.test.cpp │ ├── point_set_range_sort_range_composite.test.cpp │ ├── polynomial_interpolation.test.cpp │ ├── polynomial_taylor_shift.test.cpp │ ├── pow_of_formal_power_series.test.cpp │ ├── pow_of_matrix.test.cpp │ ├── primality_test.test.cpp │ ├── primitive_root.test.cpp │ ├── product_of_polynomial_sequence.test.cpp │ ├── queue_operate_all_composite.test.cpp │ ├── range_affine_point_get.test.cpp │ ├── range_affine_range_sum.test.cpp │ ├── range_chmin_chmax_add_range_sum.test.cpp │ ├── range_kth_smallest.test.cpp │ ├── range_reverse_range_sum.splay_tree.test.cpp │ ├── range_reverse_range_sum.treap.test.cpp │ ├── rectangle_add_point_get.2d_dual_segtree.test.cpp │ ├── rectangle_sum.persistent_segment_tree.test.cpp │ ├── rectangle_sum.range_tree.test.cpp │ ├── rooted_tree_isomorphism_classification.ahu.test.cpp │ ├── rooted_tree_isomorphism_classification.hash.test.cpp │ ├── runenumerate.test.cpp │ ├── scc.test.cpp │ ├── segment_add_get_min.test.cpp │ ├── set_xor_min.test.cpp │ ├── sharp_p_subset_sum.test.cpp │ ├── shortest_path.test.cpp │ ├── sqrt_mod.test.cpp │ ├── static_convex_hull.test.cpp │ ├── static_range_frequency.test.cpp │ ├── static_range_inversions_query.test.cpp │ ├── staticrmq.sqrt_tree.test.cpp │ ├── staticrmq.test.cpp │ ├── stirling_number_of_the_first_kind.test.cpp │ ├── stirling_number_of_the_second_kind.test.cpp │ ├── subset_convolution.test.cpp │ ├── suffixarray.test.cpp │ ├── sum_of_floor_of_linear.test.cpp │ ├── sum_of_totient_function.test.cpp │ ├── system_of_linear_equations.test.cpp │ ├── tetration_mod.test.cpp │ ├── tree_decomposition_width_2.test.cpp │ ├── tree_diameter.test.cpp │ ├── tree_path_composite_sum.test.cpp │ ├── two_edge_connected_components.test.cpp │ ├── two_sat.test.cpp │ ├── unionfind.test.cpp │ ├── vertex_add_range_contour_sum_on_tree.test.cpp │ ├── vertex_add_subtree_sum.euler_tour.test.cpp │ ├── vertex_add_subtree_sum.hld.test.cpp │ ├── vertex_set_path_composite.test.cpp │ └── zalgorithm.test.cpp └── tree ├── auxiliary_tree.hpp ├── binary_lifting.hpp ├── cartesian_tree.hpp ├── centroid_decomposition.hpp ├── euler_tour.hpp ├── euler_tour_tree.hpp ├── hld.hpp ├── lca.hpp ├── link_cut_tree.hpp ├── permutation_tree.hpp ├── range_contour_aggregation.hpp ├── rerooting.hpp ├── tree_diameter.hpp └── tree_isomorphism.hpp /.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | *.out -------------------------------------------------------------------------------- /.verify-helper/config.toml: -------------------------------------------------------------------------------- 1 | [[languages.cpp.environments]] 2 | CXX = "g++" 3 | CXXFLAGS = ["-std=c++20", "-Wall", "-Wextra"] -------------------------------------------------------------------------------- /.verify-helper/docs/_config.yml: -------------------------------------------------------------------------------- 1 | plugins: 2 | - jemoji 3 | - jekyll-remote-theme 4 | # remote_theme: jekyll/minima 5 | 6 | title: sotanishy's competitive programming library 7 | author: sotanishy 8 | description: sotanishy's code snippets for competitive programming 9 | 10 | exclude: ["icpc-document"] 11 | 12 | header_pages: 13 | - null 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sotanishy's Competitive Programming Library (C++) 2 | 3 | [![Actions Status](https://github.com/sotanishy/competitive-programming-library/workflows/verify/badge.svg)](https://github.com/sotanishy/competitive-programming-library/actions) 4 | [![GitHub Pages](https://img.shields.io/static/v1?label=GitHub+Pages&message=+&color=brightgreen&logo=github)](https://sotanishy.github.io/competitive-programming-library/) -------------------------------------------------------------------------------- /convolution/gcd_lcm_convolution.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "divisor_zeta_moebius_transform.hpp" 5 | 6 | /** 7 | * @brief GCD/LCM Convolution 8 | */ 9 | 10 | template 11 | std::vector gcd_convolution(std::vector a, std::vector b) { 12 | const int n = std::max(a.size(), b.size()); 13 | a.resize(n); 14 | b.resize(n); 15 | multiple_fzt(a); 16 | multiple_fzt(b); 17 | for (int i = 0; i < n; ++i) a[i] *= b[i]; 18 | multiple_fmt(a); 19 | return a; 20 | } 21 | 22 | template 23 | std::vector lcm_convolution(std::vector a, std::vector b) { 24 | const int n = std::max(a.size(), b.size()); 25 | a.resize(n); 26 | b.resize(n); 27 | divisor_fzt(a); 28 | divisor_fzt(b); 29 | for (int i = 0; i < n; ++i) a[i] *= b[i]; 30 | divisor_fmt(a); 31 | return a; 32 | } -------------------------------------------------------------------------------- /convolution/xor_convolution.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #include "walsh_hadamard_transform.hpp" 6 | 7 | /** 8 | * @brief Bitwise XOR Convolution 9 | */ 10 | 11 | template 12 | std::vector xor_convolution(std::vector a, std::vector b) { 13 | const int n = std::bit_ceil(std::max(a.size(), b.size())); 14 | a.resize(n); 15 | b.resize(n); 16 | fwht(a); 17 | fwht(b); 18 | for (int i = 0; i < n; ++i) a[i] *= b[i]; 19 | ifwht(a); 20 | return a; 21 | } -------------------------------------------------------------------------------- /data-structure/persistent_stack.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | template 5 | class PersistentStack { 6 | public: 7 | PersistentStack() = default; 8 | 9 | T top() const { return last->val; } 10 | 11 | bool empty() const { return last == nullptr; } 12 | 13 | PersistentStack push(const T& val) const { 14 | return PersistentStack(std::make_shared(val, last)); 15 | } 16 | 17 | PersistentStack pop() const { return PersistentStack(last->prev); } 18 | 19 | private: 20 | struct Node; 21 | using node_ptr = std::shared_ptr; 22 | 23 | struct Node { 24 | T val; 25 | node_ptr prev; 26 | Node(T val, node_ptr prev) : val(val), prev(prev) {} 27 | }; 28 | 29 | node_ptr last; 30 | 31 | explicit PersistentStack(node_ptr last) : last(last) {} 32 | }; -------------------------------------------------------------------------------- /data-structure/slide_min.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | template > 7 | class SlideMin { 8 | public: 9 | void push(T x) { 10 | while (!dq.empty() && !cmp(dq.back().first, x)) dq.pop_back(); 11 | dq.emplace_back(x, r++); 12 | } 13 | 14 | void pop() { 15 | if (dq.front().second == l) dq.pop_front(); 16 | ++l; 17 | } 18 | 19 | T get() const { return dq.front().first; } 20 | 21 | private: 22 | int l = 0, r = 0; 23 | std::deque> dq; 24 | Compare cmp; 25 | }; -------------------------------------------------------------------------------- /data-structure/unionfind/union_find.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class UnionFind { 6 | public: 7 | UnionFind() = default; 8 | explicit UnionFind(int n) : data(n, -1) {} 9 | 10 | int find(int x) { 11 | if (data[x] < 0) return x; 12 | return data[x] = find(data[x]); 13 | } 14 | 15 | void unite(int x, int y) { 16 | x = find(x); 17 | y = find(y); 18 | if (x == y) return; 19 | if (data[x] > data[y]) std::swap(x, y); 20 | data[x] += data[y]; 21 | data[y] = x; 22 | } 23 | 24 | bool same(int x, int y) { return find(x) == find(y); } 25 | 26 | int size(int x) { return -data[find(x)]; } 27 | 28 | private: 29 | std::vector data; 30 | }; -------------------------------------------------------------------------------- /docs/convolution/arbitrary_mod_convolution.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Arbitrary Mod Convolution 3 | documentation_of: ../../convolution/arbitrary_mod_convolution.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 任意の mod で畳み込みを計算する. 9 | 10 | $p_1 = 167772161, p_2 = 469762049, p_3 = 754974721$ の3つの素数を用いた数論変換による畳み込みを計算した後,Garner のアルゴリズムで答えを復元する. 11 | 12 | mod を取る前の値が $p_1 \times p_2 \times p_3$ 未満なら正しく復元できるので,mod が 32-bit 整数の場合 $n \leq 2^{22}$ 程度までなら計算できる. 13 | 14 | ## Operations 15 | 16 | - `vector convolution(vector a, vector, int mod)` 17 | - 数列 $a$ と $b$ の畳み込みを $mod$ で割った余りを計算する 18 | - 時間計算量: $O(n\log n)$ 19 | -------------------------------------------------------------------------------- /docs/convolution/convex_min_plus_convolution.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Convex Min-Plus Convolution 3 | documentation_of: ../../convolution/convex_min_plus_convolution.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 数列 $a$ と上に凸な数列 $b$ の min-plus convolution $c_i=\min_j \{a_j + b_{i-j}\}$ を求める. 9 | 10 | - `vector convex_min_plus_convolution(vector a, vector b)` 11 | - 数列 $a$ と上に凸な数列 $b$ の min-plus convolution を求める 12 | - 時間計算量: $O((n + m) \log (n+m))$ 13 | - `vector concave_max_plus_convolution(vector a, vector b)` 14 | - 数列 $a$ と下に凸な数列 $b$ の max-plus convolution を求める 15 | - 時間計算量: $O((n + m) \log (n+m))$ 16 | 17 | ## Reference 18 | 19 | - [[Tutorial] Knapsack, Subset Sum and the (max,+) Convolution](https://codeforces.com/blog/entry/98663) 20 | -------------------------------------------------------------------------------- /docs/convolution/fft.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Fast Fourier Transform 3 | documentation_of: ../../convolution/fft.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 高速 Fourier 変換 (FFT) は数列の離散 Fourier 変換を計算するアルゴリズムであり,2つの数列の畳み込みを高速に計算するのに用いられる. 9 | 10 | この実装では Cooley-Tukey のアルゴリズムを用いている. 11 | 12 | ## Operations 13 | 14 | - `void fft(vector> a)` 15 | - 数列 $a$ を高速 Fourier 変換する 16 | - 時間計算量: $O(n\log n)$ 17 | - `void ifft(vector> a)` 18 | - 数列 $a$ を逆高速 Fourier 変換する 19 | - 時間計算量: $O(n\log n)$ 20 | - `vector convolution(vector a, vector b)` 21 | - 数列 $a$ と $b$ の畳み込みを計算する 22 | - 時間計算量: $O(n\log n)$ -------------------------------------------------------------------------------- /docs/convolution/ntt.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Number Theoretic Transform 3 | documentation_of: ../../convolution/ntt.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 数論変換 (NTT) は,有限体 $\mathbb{F}_p$ 上の高速 Fourier 変換である. 9 | 10 | ## Operations 11 | 12 | - `void ntt(vector a)` 13 | - 数列 $a$ を数論変換する 14 | - 時間計算量: $O(n\log n)$ 15 | - `void intt(vector a)` 16 | - 数列 $a$ を逆数論変換する 17 | - 時間計算量: $O(n\log n)$ 18 | - `vector convolution(vector a, vector b)` 19 | - 数列 $a$ と $b$ の畳み込みを計算する 20 | - 時間計算量: $O(n\log n)$ 21 | 22 | ## Note 23 | 24 | 数列の長さ $n$ が $p - 1$ を割り切るとき,1の原子 $n$ 乗根が必ず存在する.$n$ の長さを2冪にするため,素数 $p$ は $a \times 2^k + 1$ の形に表したとき $k$ が十分大きいものを用いる. 25 | 26 | 以下の `p` と原子根の組み合わせがよく用いられる: 27 | - (167772161, 3) 28 | - (469762049, 3) 29 | - (754974721, 11) 30 | - (998244353, 3) 31 | - (1224736769, 3) ($2p$ が 32-bit 符号付き整数に収まらないので,私の `Modint` では扱えない) 32 | 33 | $k$ の値はそれぞれ,25, 26, 24, 23, 24である. -------------------------------------------------------------------------------- /docs/convolution/relaxed_convolution.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Relaxed Convolution 3 | documentation_of: ../../convolution/relaxed_convolution.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Relaxed convolution は,畳み込みをオンラインで処理するアルゴリズムである.すなわち,数列 $F, G$ の項が前から順番に与えられたとき,それらの畳み込み $H=F*G$ の各項を前から順番に返す. 9 | 10 | ## Operations 11 | 12 | - `mint get(mint a, mint b)` 13 | - $F_n=a,G_n=b$ が与えられたとき, $H_n=\sum_{k=0}^n F_k G_{n-k}$ を返す. 14 | - 時間計算量: $\mathrm{amortized}\, O(N (\log N)^2)$ 15 | 16 | ## Reference 17 | 18 | - [オンライン畳み込み - Qiita](https://qiita.com/Kiri8128/items/1738d5403764a0e26b4c) 19 | - verify: [https://atcoder.jp/contests/abc315/submissions/44768767](https://atcoder.jp/contests/abc315/submissions/44768767) -------------------------------------------------------------------------------- /docs/data-structure/cht/convex_hull_trick.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Convex Hull Trick 3 | documentation_of: ../../../data-structure/cht/convex_hull_trick.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Convex hull trick は,直線集合 $L$ への追加クエリと最小値クエリを効率的に行う手法である. 9 | 10 | この実装では,追加する直線の傾きが単調非増加である必要がある.傾きに単調性がないときは平衡二分探索木を用いた CHT または Li Chao tree を使用せよ. 11 | 12 | 空間計算量: $O(n)$ 13 | 14 | ## Operations 15 | 16 | - `void add(T a, T b)` 17 | - 直線 $ax + b$ を $L$ に追加する 18 | - 時間計算量: $\mathrm{amortized}\ O(1)$ 19 | - `T get(T x)` 20 | - 与えられた $x$ に対し,$L$ の中で最小値を取る直線の値を求める 21 | - 時間計算量: $\mathrm{amortized}\ O(1)$ 22 | 23 | ## Reference 24 | 25 | - [Convex-Hull Trick](https://satanic0258.hatenablog.com/entry/2016/08/16/181331) -------------------------------------------------------------------------------- /docs/data-structure/cht/convex_hull_trick_binsearchtree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Convex Hull Trick (Binary Search Tree) 3 | documentation_of: ../../../data-structure/cht/convex_hull_trick_binsearchtree.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Convex hull trick は,直線集合 $L$ への追加クエリと最小値クエリを効率的に行う手法である.本実装では平衡二分探索木を用いており,追加する直線の傾きの単調性が無くても動作する. 9 | 10 | 空間計算量: $O(n)$ 11 | 12 | ## Operations 13 | 14 | - `T add(T a, T b)` 15 | - 直線 $ax + b$ を $L$ に追加する 16 | - 時間計算量: $O(\log n)$ 17 | - `T get(T x)` 18 | - 与えられた $x$ に対し,$L$ の中で最小値を取る直線の値を求める 19 | - 時間計算量: $O(\log n)$ -------------------------------------------------------------------------------- /docs/data-structure/cht/li_chao_tree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Li Chao Tree 3 | documentation_of: ../../../data-structure/cht/li_chao_tree.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Li Chao tree は,直線及び線分の集合をセグメント木で管理し,与えられた $x$ 座標での最小値を取得するデータ構造である. 9 | 10 | ## Operations 11 | 12 | - `LiChaoTree(vector xs)` 13 | - クエリに用いる $x$ 座標を受け取り,Li Chao tree を構築する 14 | - 時間計算量: $O(n)$ 15 | - `void add_line(T a, T b)` 16 | - 直線 $y = ax + b$ を追加する 17 | - 時間計算量: $O(\log n)$ 18 | - `void add_segment(T a, T b, T xl, T xr)` 19 | - 線分 $y = ax + b \quad (x \in [x_l, x_r))$ を追加する 20 | - 時間計算量: $O(\log^2 n)$ 21 | - `T get(T x)` 22 | - $x$ での最小値を取得する 23 | - 時間計算量: $O(\log n)$ 24 | 25 | ## Reference 26 | 27 | - [Li Chao Treeのメモ](https://smijake3.hatenablog.com/entry/2018/06/16/144548) -------------------------------------------------------------------------------- /docs/data-structure/cht/nonlinear_convex_hull_trick.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Nonlinear Convex Hull Trick 3 | documentation_of: ../../../data-structure/cht/nonlinear_convex_hull_trick.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 互いにたかだか 1 回しか交わらない関数の集合への追加クエリと最小値取得クエリを処理する. 9 | 10 | 追加クエリは次の意味での単調性を満たす必要がある:最も新しく追加された関数は,十分大きな $x$ において,集合内の関数の中で最小値を取る. 11 | 12 | 空間計算量: $O(n)$ 13 | 14 | ## Operations 15 | 16 | - `void add(F f)` 17 | - 関数 $f$ を集合に追加する 18 | - 時間計算量: $\mathrm{amortized}\ O(\log n)$ 19 | - `T get(T x)` 20 | - 与えられた $x$ に対し,最小値を取る関数の値を求める 21 | - 時間計算量: $\mathrm{amortized}\ O(1)$ 22 | 23 | ## Reference 24 | 25 | - verify: [https://atcoder.jp/contests/abc373/submissions/58145171](https://atcoder.jp/contests/abc373/submissions/58145171) -------------------------------------------------------------------------------- /docs/data-structure/disjoint_sparse_table.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Disjoint Sparse Table 3 | documentation_of: ../../data-structure/disjoint_sparse_table.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Disjoint sparse table は,モノイド $(T, \cdot, e)$ の静的な列の区間積を高速に計算するデータ構造である.Sparse table と違って二項演算 $\cdot$ に冪等性を要求しない. 9 | 10 | 空間計算量: $O(n \log n)$ 11 | 12 | ## Operations 13 | 14 | - `DisjointSparseTable(vector v)` 15 | - `v`の要素から disjoint sparse table を構築する 16 | - 時間計算量: $O(n \log n)$ 17 | - `T fold(int l, int r)` 18 | - 区間 $[l, r)$ の値を fold する 19 | - 時間計算量: $O(1)$ 20 | 21 | ## Reference 22 | 23 | - [[Tutorial] Disjoint Sparse Table](https://discuss.codechef.com/t/tutorial-disjoint-sparse-table/17404) 24 | - [Disjoint Sparse Table と セグ木に関するポエム](https://noshi91.hatenablog.com/entry/2018/05/08/183946) -------------------------------------------------------------------------------- /docs/data-structure/kd_tree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: k-d Tree 3 | documentation_of: ../../data-structure/kd_tree.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | k-d 木は,$k$ 次元空間の点を保持し,効率的に範囲探索を行うデータ構造である.この実装は2次元空間の長方形領域の探索を提供する. 9 | 10 | 空間計算量: $O(n)$ 11 | 12 | ## Operations 13 | 14 | - `void add_point(int id, T x, T y)` 15 | - ラベル `id` の点 $(x, y)$ を追加する 16 | - 時間計算量: $O(1)$ 17 | - `void build()` 18 | - k-d 木を構築する 19 | - 時間計算量: $O(n\log^2 n)$ 20 | - `vector search(T sx, T tx, T sy, T ty)` 21 | - $(sx, sy)$ から $(tx, ty)$ までの長方形領域内の点のラベルを返す 22 | - 時間計算量: $O(\sqrt{N} + m)$.$m$ は領域内の点の数 23 | 24 | ## Reference 25 | 26 | - [kd木](https://ja.wikipedia.org/wiki/Kd%E6%9C%A8) -------------------------------------------------------------------------------- /docs/data-structure/leftist_heap.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Leftist Heap 3 | documentation_of: ../../data-structure/leftist_heap.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Leftist heap は,meldable heap (マージ可能ヒープ) の一種である. 9 | 10 | ## Operations 11 | 12 | - `static LeftistHeap meld(LeftistHeap a, LeftistHeap b)` 13 | - $a$ と $b$ を併合する 14 | - 時間計算量: $O(\log n)$ 15 | - `pair top()` 16 | - 最小値とその id を返す 17 | - 時間計算量: $O(1)$ 18 | - `void pop()` 19 | - 最小値を削除する 20 | - 時間計算量: $O(\log n)$ 21 | - `void push(int id, T x)` 22 | - 値 $x$ を持つ要素 $id$ を追加する 23 | - 時間計算量: $O(\log n)$ 24 | - `void add(T x)` 25 | - 全ての要素の値に $x$ を加算する 26 | - 時間計算量: $O(1)$ 27 | 28 | ## Reference 29 | 30 | - [Leftist Heap & Skew Heap](http://hos.ac/blog/#blog0001) -------------------------------------------------------------------------------- /docs/data-structure/min_max_heap.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Min-Max Heap 3 | documentation_of: ../../data-structure/min_max_heap.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Min-max heap は,要素の最大値と最小値を取得することのできるヒープである. 9 | 10 | ## Operations 11 | 12 | - `MinMaxHeap(vector v)` 13 | - $v$ の要素から min-max heap を構築する 14 | - 時間計算量: $O(n)$ 15 | - `void insert(T x)` 16 | - $x$ を挿入する 17 | - 時間計算量: $O(\log n)$ 18 | - `T min_element()` 19 | - 最小値を求める 20 | - 時間計算量: $O(1)$ 21 | - `T max_element()` 22 | - 最大値を求める 23 | - 時間計算量: $O(1)$ 24 | - `void erase_min()` 25 | - 最小値を削除する 26 | - 時間計算量: $O(\log n)$ 27 | - `void erase_max()` 28 | - 最大値を削除する 29 | - 時間計算量: $O(\log n)$ 30 | 31 | ## Reference 32 | 33 | - [Min-max heap - Wikipedia](https://en.wikipedia.org/wiki/Min-max_heap) -------------------------------------------------------------------------------- /docs/data-structure/persistent_array.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Persistent Array 3 | documentation_of: ../../data-structure/persistent_array.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 永続配列は,過去のバージョンを保持する配列である.永続配列の要素を変更したとき,変更された値を保持する新しい配列を生成する. 9 | 10 | 空間計算量: $O(m b \log_b n)$, $m$ は変更の数 11 | 12 | ## Operations 13 | 14 | - `PersistentArray(vector v)` 15 | - `v` の要素から永続配列を構築する 16 | - 時間計算量: $O(nb \log_b n)$ 17 | - `T get(int k)` 18 | - $k$ 番目の要素を返す 19 | - 時間計算量: $O(\log_b n)$ 20 | - `PersistentArray set(int k, T x)` 21 | - $k$ 番目の要素を $x$ に変更した永続配列を返す 22 | - 時間計算量: $O(b \log_b n)$ 23 | 24 | ## Reference 25 | 26 | - [ゼロから作る永続データ構造](https://qiita.com/wotsushi/items/72e7f8cdd674741ffd61) -------------------------------------------------------------------------------- /docs/data-structure/persistent_queue.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Persistent Queue 3 | documentation_of: ../../data-structure/persistent_queue.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 永続キューは,過去のバージョンを保持するキューである.この実装では内部で永続配列を用いている. 9 | 10 | 空間計算量: $O(m \log n)$, $m$ は変更の数 11 | 12 | ## Operations 13 | 14 | - `int size()` 15 | - キューの要素数を返す 16 | - 時間計算量: $O(1)$ 17 | - `bool empty()` 18 | - 時間計算量: $O(1)$ 19 | - `T front()` 20 | - 先頭の要素を返す 21 | - 時間計算量: $O(1)$ 22 | - `T back()` 23 | - 末尾の要素を返す 24 | - 時間計算量: $O(1)$ 25 | - `PersistentQueue push(T val)` 26 | - `val` をキューの末尾に追加する 27 | - 時間計算量: $O(\log n)$ 28 | - `PersistentQueue pop()` 29 | - キューの先頭要素を削除する 30 | - 時間計算量: $O(1)$ -------------------------------------------------------------------------------- /docs/data-structure/persistent_stack.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Persistent Stack 3 | documentation_of: ../../data-structure/persistent_stack.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 永続スタックは,過去のバージョンを保持するスタックである. 9 | 10 | 空間計算量: $O(m)$, $m$ は変更の数 11 | 12 | ## Operations 13 | 14 | - `bool empty()` 15 | - 時間計算量: $O(1)$ 16 | - `T top()` 17 | - 先頭の要素を返す 18 | - 時間計算量: $O(1)$ 19 | - `PersistentStack push(T val)` 20 | - `val` を先頭に追加する 21 | - 時間計算量: $O(1)$ 22 | - `PersistentStack pop()` 23 | - 先頭の要素を削除する 24 | - 時間計算量: $O(1)$ 25 | 26 | ## Reference 27 | 28 | - [ゼロから作る永続データ構造](https://qiita.com/wotsushi/items/72e7f8cdd674741ffd61) -------------------------------------------------------------------------------- /docs/data-structure/quadtree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Quadtree 3 | documentation_of: ../../data-structure/quadtree.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 四分木は,二次元領域を扱うデータ構造である.この実装では,可換モノイドの一点更新と長方形領域和を扱う.一点更新は高速だが,長方形領域取得は最悪計算量が悪い.実用上は愚直よりは高速であると思われる. 9 | 10 | 空間計算量: $O(m\log n)$, $m$ は点の数 11 | 12 | ## Operations 13 | 14 | - `Quadtree(int n)` 15 | - $n \times n$ の領域を扱う四分木を構築する. 16 | - 時間計算量: $O(\log n)$ 17 | - `T get(int x, int y)` 18 | - 点 $(x, y)$ の値を返す 19 | - 時間計算量: $O(\log n)$ 20 | - `void update(int x, int y, T val)` 21 | - 点 $(x, y)$ の値を `val` に更新する 22 | - 時間計算量: $O(\log n)$ 23 | - `T fold(int l, int r, int b, int t)` 24 | - 領域 ${(x, y) : x \in [l, r),\ y \in [b, t)}$ 内の点を fold した値を返す 25 | - 時間計算量: $O(m\log n)$ -------------------------------------------------------------------------------- /docs/data-structure/range_fenwick_tree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Fenwick Tree with Range Update 3 | documentation_of: ../../data-structure/range_fenwick_tree.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 接頭辞和を扱う Fenwick tree を2つ使うことで,区間加算を実現できる. 9 | 10 | 空間計算量: $O(n)$ 11 | 12 | ## Operations 13 | 14 | - `RangeFenwickTree(int n)` 15 | - サイズ`n`で要素がすべて $0$ の区間更新 Fenwick tree を構築する 16 | - 時間計算量: $O(n)$ 17 | - `T prefix_sum(int i)` 18 | - $[0, i)$ の総和を計算する 19 | - 時間計算量: $O(\log n)$ 20 | - `void add(int l, int r, T x)` 21 | - 区間 $[l, r)$ に $x$ を加える 22 | - 時間計算量: $O(\log n)$ 23 | 24 | ## Reference 25 | 26 | - [Binary Indexed Tree のはなし](http://hos.ac/slides/20140319_bit.pdf) -------------------------------------------------------------------------------- /docs/data-structure/range_tree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Range Tree 3 | documentation_of: ../../data-structure/range_tree.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 領域木は,2次元平面の長方形領域内の点に対する値の総和クエリを扱うデータ構造である. 9 | 10 | 空間計算量: $O(n\log n)$ 11 | 12 | ## Operations 13 | 14 | - `RangeTree(vector>> pts)` 15 | - `pts` の点から領域木を構築する.点は $(x, y, v)$ の形式で与えられる. 16 | - 時間計算量: $O(n\log n)$ 17 | - `T fold(X sx, X tx, Y sy, Y ty)` 18 | - 長方形領域 $[sx, tx) \times [sy, ty)$ 内の点に対する値の総和を計算する 19 | - 時間計算量: $O((\log n)^2)$ 20 | 21 | ## Reference 22 | 23 | - [領域木の布教](https://mugen1337.hatenablog.com/entry/2021/05/22/224041) 24 | -------------------------------------------------------------------------------- /docs/data-structure/segtree/dynamic_segment_tree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Dynamic Segment Tree 3 | documentation_of: ../../../data-structure/segtree/dynamic_segment_tree.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 動的セグメント木は,モノイド $(T, \cdot, e)$ の列に対する一点更新と区間取得を提供するデータ構造である.必要なノードだけを動的に構築することで, $n$ が非常に大きい場合でも効率的に値を管理することができる. 9 | 10 | 空間計算量: $O(m\log n)$.$m$ は追加した要素の数 11 | 12 | ## Operations 13 | 14 | - `DynamicSegmentTree(long long n)` 15 | - サイズ`n`で要素がすべて単位元 $e$ の動的セグメント木を構築する 16 | - 時間計算量: $O(\log n)$ 17 | - `T operator[](long long k)` 18 | - $k$ 番目の要素を返す 19 | - 時間計算量: $O(\log n)$ 20 | - `void update(long long k, T x)` 21 | - $k$ 番目の要素を $x$ に更新する 22 | - 時間計算量: $O(\log n)$ 23 | - `T fold(long long l, long long r)` 24 | - 区間 $[l, r)$ の値を fold する 25 | - 時間計算量: $O(\log n)$ -------------------------------------------------------------------------------- /docs/data-structure/segtree/segment_tree_2d.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 2D Segment Tree 3 | documentation_of: ../../../data-structure/segtree/segment_tree_2d.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 2D セグメント木は,モノイド $(T, \cdot, e)$ の重みを持つ2次元平面上の点集合に対する一点更新と矩形領域積取得を提供するデータ構造である. 9 | 10 | この実装では,重みをもたせる点を先読みして初期化時に渡す必要がある. 11 | 12 | 空間計算量: $O(n)$ 13 | 14 | ## Operations 15 | 16 | - `SegmentTree2D(vector> pts)` 17 | - `pts` の点に対する 2D セグメント木を初期化する 18 | - 時間計算量: $O(n\log n)$ 19 | - `void update(X x, Y y, T val)` 20 | - 点 $(x, y)$ の重みを $val$ に更新する 21 | - 時間計算量: $O((\log n)^2)$ 22 | - `T fold(X sx, X tx, Y sy, Y ty)` 23 | - 矩形領域 $[s_x, t_x) \times [s_y, t_y)$ 内の点の重みの積を取得する 24 | - 時間計算量: $O((\log n)^2)$ 25 | -------------------------------------------------------------------------------- /docs/data-structure/slide_min.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Sliding Window Minimum 3 | documentation_of: ../../data-structure/slide_min.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | スライド最小値は,全順序集合 $T$ を扱い,要素の最小値を求めることができるキューである. 9 | 10 | ## Operations 11 | 12 | - `void push(T x)` 13 | - $x$ をキューの末尾に追加する 14 | - 時間計算量: $\mathrm{amortized}\ O(1)$ 15 | - `void pop()` 16 | - キューの先頭要素を削除する 17 | - 時間計算量: $O(1)$ 18 | - `T get()` 19 | - キューの要素全体の最小値/最大値を返す 20 | - 時間計算量: $O(1)$ -------------------------------------------------------------------------------- /docs/data-structure/sliding_window_aggregation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Sliding Window Aggregation 3 | documentation_of: ../../data-structure/sliding_window_aggregation.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Sliding window aggregation は,半群 $(T, \cdot)$ を扱い,要素の総和の計算が可能なキューである.スタックを2つ用いてキューをシミュレートする. 9 | 10 | ## Operations 11 | 12 | - `void push(T x)` 13 | - $x$ をキューの末尾に追加する 14 | - 時間計算量: $O(1)$ 15 | - `void pop()` 16 | - キューの先頭要素を削除する 17 | - 時間計算量: $\mathrm{amortized}\ O(1)$ 18 | - `bool empty()` 19 | - キューが空かどうか判定する 20 | - 時間計算量: $O(1)$ 21 | - `T fold()` 22 | - キューの要素全体の演算結果を返す 23 | - 時間計算量: $O(1)$ 24 | 25 | ## Reference 26 | 27 | - [Sliding Window Aggregation](https://scrapbox.io/data-structures/Sliding_Window_Aggregation) 28 | - [Constant-Time Sliding Window Aggregation](http://hirzels.com/martin/papers/tr15-rc25574-daba.pdf) -------------------------------------------------------------------------------- /docs/data-structure/sparse_table.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Sparse Table 3 | documentation_of: ../../data-structure/sparse_table.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Sparse table は,冪等モノイド $(T, \cdot, e)$ の静的な列の区間積を高速に計算するデータ構造である. 9 | 10 | 冪等な二項演算とは, $\forall a \in T, a \cdot a = a$ が成り立つような写像 $\cdot: T \times T \rightarrow T$ である.冪等な二項演算には,max, min, gcd, bitwise and, bitwise or などがある. 11 | 12 | 空間計算量: $O(n \log n)$ 13 | 14 | ## Operations 15 | 16 | - `SparseTable(vector v)` 17 | - `v`の要素から sparse table を構築する 18 | - 時間計算量: $O(n \log n)$ 19 | - `T fold(int l, int r)` 20 | - 区間 $[l, r)$ の値を fold する 21 | - 時間計算量: $O(1)$ 22 | 23 | ## Reference 24 | 25 | - [Sparse Table](https://cp-algorithms.com/data_structures/sparse-table.html) -------------------------------------------------------------------------------- /docs/data-structure/unionfind/persistent_union_find.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Persistent Union Find 3 | documentation_of: ../../../data-structure/unionfind/persistent_union_find.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 永続 union find は,過去のバージョンを保持する union find である. 9 | 10 | 空間計算量: $O(n + m \log n)$, $m$ は変更の数 11 | 12 | ## Operations 13 | 14 | - `PersistentUnionFind(int n)` 15 | - サイズ`n` の永続 union find を構築する 16 | - 時間計算量: $O(n \log n)$ 17 | - `int find(int x)` 18 | - $x$ が属する木の根を返す 19 | - 時間計算量: $O(\log^2 n)$ 20 | - `PersistentUnionFind unite(int x, int y)` 21 | - $x$ が属する集合と $y$ が属する集合を連結する 22 | - 時間計算量: $O(\log^2 n)$ 23 | - `bool same(int x, int y)` 24 | - $x$ と $y$ が同じ集合に属するかを判定する 25 | - 時間計算量: $O(\log^2 n)$ 26 | - `int size(int x)` 27 | - $x$ が属する集合の大きさを返す 28 | - 時間計算量: $O(\log^2 n)$ 29 | 30 | ## Reference 31 | 32 | - [A Persistent Union-Find Data Structure](https://www.lri.fr/~filliatr/ftp/publis/puf-wml07.pdf) -------------------------------------------------------------------------------- /docs/dp/hu_tucker.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hu-Tucker Algorithm 3 | documentation_of: ../../dp/hu_tucker.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Hu-Tucker のアルゴリズムは,最適二分探索木問題を高速に解くアルゴリズムである. 9 | 10 | 正当性の証明は難しいらしい. 11 | 12 | ## Operations 13 | 14 | - `T hu_tucker(vector w)` 15 | - 各頂点の重み $w_i$ が与えられたとき,最適二分探索木の重みを求める. 16 | - 時間計算量: $O(n\log n)$ 17 | 18 | ## Reference 19 | 20 | - [C - 最適二分探索木](https://atcoder.jp/contests/atc002/tasks/atc002_c) -------------------------------------------------------------------------------- /docs/dp/monge_shortest_path.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Monge Shortest Path 3 | documentation_of: ../../dp/monge_shortest_path.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Monge な辺重みを持つ完全 DAG 上の最短距離を求める.この問題は LARSCH algorithm によって $O(N)$ 時間で解けるが,この実装ではより実装が簡単で定数倍高速な $O(N \log N)$ 時間の簡易版 LARSCH algorithm を用いている. 9 | 10 | - `vector monge_shortest_path(int n, F cost)` 11 | - 辺 $(i,j)$ の重みが $\mathrm{cost}(i,j)$ で与えられる $n$ 頂点完全 DAG の頂点 $0$ から各頂点への最短距離を返す 12 | - 時間計算量: $O(n \log n)$ 13 | 14 | ## Reference 15 | 16 | - [簡易版 LARSCH Algorithm - noshi91のメモ](https://noshi91.hatenablog.com/entry/2023/02/18/005856) 17 | - verify: [https://atcoder.jp/contests/abc355/submissions/53788299](https://atcoder.jp/contests/abc355/submissions/53788299) -------------------------------------------------------------------------------- /docs/dp/monotone_minima.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Monotone Minima 3 | documentation_of: ../../dp/monotone_minima.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Monotone minima は,monotone 行列の各行の argmin を高速に求めるアルゴリズムである. 9 | 10 | $n \times m$ 行列 $A$ が monotone であるとは, 11 | 12 | $\mathrm{argmin} A_{i,\ast} \leq \mathrm{argmin} A_{i+1,\ast}$ が成り立つことである. 13 | 14 | $A$ が更に totally monotone ($A$ の任意の部分行列が monotone) であれば,SMAWK algorithm という更に高速なアルゴリズムが存在する. 15 | 16 | - `vector monotone_minima(int n, int m, F f)` 17 | - $A_{i,j}=f(i,j)$ である $n \times m$ 行列 $A$ の各行の argmin を求める 18 | - 時間計算量: $O((n + m)\log n)$ 19 | 20 | ## Reference 21 | 22 | - [Totally Monotone Matrix Searching (SMAWK algorithm)](https://topcoder-g-hatena-ne-jp.jag-icpc.org/spaghetti_source/20120923/) -------------------------------------------------------------------------------- /docs/dp/smawk.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: SMAWK Algorithm 3 | documentation_of: ../../dp/smawk.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | SMAWK algorithm は,totally monotone 行列の各行の argmin を高速に求めるアルゴリズムである. 9 | 10 | 単に monotone の場合は monotone minima が使える. 11 | 12 | - `vector smawk(int n, int m, F f)` 13 | - $A_{i,j}=f(i,j)$ である $n \times m$ 行列 $A$ の各行の argmin を求める 14 | - 時間計算量: $O(n + m)$ 15 | 16 | ## Note 17 | 18 | 多分壊れてる.monotone minima使って 19 | 20 | ## Reference 21 | 22 | - [Totally Monotone Matrix Searching (SMAWK algorithm)](https://topcoder-g-hatena-ne-jp.jag-icpc.org/spaghetti_source/20120923/) 23 | - [The SMAWK Algorithm](http://web.cs.unlv.edu/larmore/Courses/CSC477/monge.pdf) 24 | - [SMAWK Algorithm](https://noshi91.github.io/Library/algorithm/smawk.cpp.html) -------------------------------------------------------------------------------- /docs/flow/dinic.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Dinic's Algorithm 3 | documentation_of: ../../flow/dinic.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Dinic のアルゴリズムは,フローネットワークの最大流を求めるアルゴリズムである.始点からの最短距離を BFS で計算し,残余グラフの増加パスを DFS で見つけ,そのパスにフローを流すことを繰り返す. 9 | 10 | ## Operations 11 | 12 | - `Dinic(int n)` 13 | - グラフを $n$ 頂点で初期化する 14 | - 時間計算量: $O(n)$ 15 | - `void add_edge(int u, int v, T cap)` 16 | - 容量 $cap$ の辺 $(u, v)$ を追加する 17 | - 時間計算量: $O(1)$ 18 | - `T max_flow(int s, int t)` 19 | - 始点 $s$ から終点 $t$ への最大流を求める 20 | - 時間計算量: $O(V^2E)$ 21 | 22 | ## Reference 23 | 24 | - [Dinic 法とその時間計算量 - みさわめも](https://misawa.github.io/others/flow/dinic_time_complexity.html) -------------------------------------------------------------------------------- /docs/flow/ford_fulkerson.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Ford-Fulkerson Algorithm 3 | documentation_of: ../../flow/ford_fulkerson.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Ford-Fulkerson のアルゴリズムは,フローネットワークの最大流を求めるアルゴリズムである.残余グラフの増加パスを DFS で見つけ,そのパスにフローを流すことを繰り返す. 9 | 10 | ## Operations 11 | 12 | - `FordFulkerson(int n)` 13 | - グラフを $n$ 頂点で初期化する 14 | - 時間計算量: $O(n)$ 15 | - `void add_edge(int u, int v, T cap)` 16 | - 容量 $cap$ の辺 $(u, v)$ を追加する 17 | - 時間計算量: $O(1)$ 18 | - `T max_flow(int s, int t)` 19 | - 始点 $s$ から終点 $t$ への最大流を求める 20 | - 時間計算量: $O(Ef)$ -------------------------------------------------------------------------------- /docs/geometry/convex_hull.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Convex Hull 3 | documentation_of: ../../geometry/convex_hull.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 与えられた点の凸包を求める.この実装では Graham scan アルゴリズムを用いている. 9 | 10 | ## Operations 11 | 12 | - `vector convex_hull(vector pts, bool strict = true)` 13 | - `pts` の凸包の境界の頂点を返す. `strict = true` ならば,凸包の頂点のみ返す. 14 | - 時間計算量: $O(n\log n)$ -------------------------------------------------------------------------------- /docs/geometry/minimum_bounding_circle.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Minimum Bounding Circle 3 | documentation_of: ../../geometry/minimum_bounding_circle.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 与えられた点群の最小包含円を求める.Welzl のアルゴリズムを用いている. 9 | 10 | ## Operations 11 | 12 | - `Circle minimum_bounding_circle(vector pts)` 13 | - `pts` の最小包含円を返す 14 | - 時間計算量: $\mathrm{expected}\ O(n)$ 15 | 16 | ## Reference 17 | 18 | - [Smallest circle problem - Wikipedia](https://en.wikipedia.org/wiki/Smallest-circle_problem) 19 | - verify: [https://atcoder.jp/contests/abc151/submissions/31596027](https://atcoder.jp/contests/abc151/submissions/31596027) 20 | 21 | -------------------------------------------------------------------------------- /docs/graph/assignment.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Assignment Problem (Maximum Weight Perfect Matching) 3 | documentation_of: ../../graph/assignment.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 割当問題 (最大重み完全マッチング) を Hungarian 法で解く. 9 | 10 | ## Operations 11 | 12 | - `vector assignment(vector> a)` 13 | - $\sum_{i=1}^n a_{i,p_i}$ を最大化する $(p_i)_{i=1,\dots,n}$ を返す 14 | - 時間計算量: $O(n^3)$ 15 | 16 | ## Reference 17 | 18 | - Lee, Jon. *A First Course in Combinatorial Optimization*. Cambridge: Cambridge University Press, 2010 19 | - [Assignment Problem and Hungarian Algorithm](https://www.topcoder.com/thrive/articles/Assignment%20Problem%20and%20Hungarian%20Algorithm) -------------------------------------------------------------------------------- /docs/graph/biconnected_components.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Biconnected Components 3 | documentation_of: ../../graph/biconnected_components.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 二重頂点連結成分は,どの1頂点を取り除いても連結であるような部分グラフである.つまり,関節点を含まない部分グラフである. 9 | 10 | 関節点と二重頂点連結成分を結んで構成した木は block cut tree と呼ばれる. 11 | 12 | 空間計算量: $O(V + E)$ 13 | 14 | ## Operations 15 | 16 | - `vector> biconnected_components(vector> G, Lowlink low)` 17 | - グラフ $G$ の隣接リストと,$G$ の lowlink 構造体が与えられたとき,$G$ を二重頂点連結成分分解する.$G$ の二重頂点連結成分を返す 18 | - 時間計算量: $O(V + E)$ 19 | - `vector> block_cut_tree(vector> blocks, vector cuts)` 20 | - ブロック(二重頂点連結成分)とカット(関節点)のリストが与えられたときに,対応する block cut tree の隣接リストを返す 21 | - 時間計算量: $O(B + C)$ 22 | -------------------------------------------------------------------------------- /docs/graph/bipartite_matching.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Bipartite Matching 3 | documentation_of: ../../graph/bipartite_matching.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 二部グラフの最大マッチングを Hopcroft-Karp アルゴリズムで求める.これは Dinic のアルゴリズムの特殊ケースである. 9 | 10 | ## Operations 11 | 12 | - `BipartiteMatching(int U, int V)` 13 | - 頂点数 $(U, V)$ で初期化する 14 | - `void add_edge(int u, int v)` 15 | - 辺 $(u, v)$ を追加する 16 | - `vector> max_matching()` 17 | - 二部グラフの最大マッチングを一つ返す 18 | - 時間計算量: $O(E\sqrt{U+V})$ 19 | 20 | ## Reference 21 | 22 | - [Hopcroft–Karp algorithm - Wikipedia](https://en.wikipedia.org/wiki/Hopcroft%E2%80%93Karp_algorithm) 23 | -------------------------------------------------------------------------------- /docs/graph/chromatic_number.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Chromatic Number 3 | documentation_of: ../../graph/chromatic_number.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | グラフの彩色数は,グラフの隣り合う頂点の色が異なるように頂点を彩色するために必要な最小の色の数である. 9 | 10 | ## Operations 11 | 12 | - `int chromatic_number(vector> G)` 13 | - グラフ $G$ の隣接行列が与えられたとき,$G$ の彩色数を求める 14 | - 時間計算量: $O(n 2^n)$ 15 | 16 | ## Reference 17 | 18 | - [指数時間アルゴリズム入門](https://www.slideshare.net/wata_orz/ss-12131479) -------------------------------------------------------------------------------- /docs/graph/complement_bfs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: BFS on a Complement Graph 3 | documentation_of: ../../graph/complement_bfs.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 補グラフで幅優先探索を行う. 9 | 10 | ## Operations 11 | 12 | - `vector complement_bfs(vector> Gcomp, int s)` 13 | - グラフ $G$ の補グラフが与えられたとき, $G$ 上で $s$ から各頂点への最短距離を求める 14 | - 時間計算量: $O(n+m)$ 15 | 16 | ## Reference 17 | 18 | - [ABC319 G - Counting Shortest Paths 解説](https://atcoder.jp/contests/abc319/editorial/7120) 19 | - verify: [https://atcoder.jp/contests/abc319/submissions/45437018](https://atcoder.jp/contests/abc319/submissions/45437018) 20 | -------------------------------------------------------------------------------- /docs/graph/enumerate_cliques.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Clique Enumeration 3 | documentation_of: ../../graph/enumerate_cliques.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | クリークを全列挙する. 9 | 10 | クリークの個数は高々 $2^{\sqrt{2E}}$ 個である. 11 | 12 | ## Operations 13 | 14 | - `vector> enumerate_cliques(vector> G)` 15 | - グラフ $G$ の隣接行列が与えられたとき, $G$ のクリークを全列挙する. 16 | - 時間計算量: $O(2^{\sqrt{2E}} V)$ 17 | 18 | 19 | ## Reference 20 | 21 | - [指数時間アルゴリズム入門](https://www.slideshare.net/wata_orz/ss-12131479) -------------------------------------------------------------------------------- /docs/graph/enumerate_triangles.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Triangle Enumeration 3 | documentation_of: ../../graph/enumerate_triangles.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 無向グラフの三角形を全列挙する. 9 | 10 | ## Operations 11 | 12 | - `vector> enumerate_triangles(vector> G)` 13 | - グラフ $G$ の隣接リストが与えられたとき,$G$ の三角形を全列挙する. 14 | - 時間計算量: $O(E\sqrt{E})$ 15 | 16 | ## Reference 17 | 18 | - [Enumerate Triangles(三角形全列挙)](https://ei1333.github.io/library/graph/others/enumerate-triangles.hpp.html) -------------------------------------------------------------------------------- /docs/graph/eulerian_walk.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Eulerian Walk 3 | documentation_of: ../../graph/eulerian_walk.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Euler 路 (グラフのすべての辺を通る路) を一つ見つける. 9 | 10 | 奇数次の頂点が0個なら Euler 閉路が存在する.奇数次の頂点が2個なら閉路でない Euler 路が存在する.それ以外のときは Euler 路は存在しない. 11 | 12 | この実装では Hierholzer のアルゴリズムを用いている. 13 | 14 | ## Operations 15 | 16 | - `vector eulerian_walk(vector> edges, int V)` 17 | - 頂点数 $V$ のグラフ $G$ の辺集合が与えられたとき,$G$ の Euler 路に現れる頂点を順番に返す.存在しない場合は空リストを返す. 18 | - 時間計算量: $O(E)$ 19 | -------------------------------------------------------------------------------- /docs/graph/general_matching.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: General Matching 3 | documentation_of: ../../graph/general_matching.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 一般グラフの最大マッチングを,Edmonds の花アルゴリズムで求める. 9 | 10 | ## Operations 11 | 12 | - `GeneralMatching(int n)` 13 | - 頂点数 $n$ で初期化する 14 | - `void add_edge(int u, int v)` 15 | - 辺 $(u, v)$ を追加する 16 | - `vector> max_matching()` 17 | - 一般グラフの最大マッチングを一つ返す 18 | - 時間計算量: $O(n^3)$ 19 | 20 | ## Reference 21 | 22 | - Lee, Jon. *A First Course in Combinatorial Optimization*. Cambridge: Cambridge University Press, 2010 23 | - [[Tutorial] Blossom Algorithm for General Matching in O(n^3) - Codeforces](https://codeforces.com/blog/entry/92339) -------------------------------------------------------------------------------- /docs/graph/junction_tree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Junction Tree (Width 2) 3 | documentation_of: ../../graph/junction_tree.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 与えられた木の木幅が $2$ 以下か判定し,そうならば木幅 $2$ の木分解を構築する. 9 | 10 | 空間計算量: $O(V + E)$ 11 | 12 | ## Operations 13 | 14 | - `JunctionTreeWidth2(vector> G)` 15 | - グラフ $G$ の隣接リストが与えられたとき,$G$ の木幅 $2$ の木分解を求める. 16 | - 時間計算量: $O(E\log V)$ 17 | - `bool is_treewidth_2()` 18 | - 木幅が $2$ 以下か判定する 19 | - `vector get_nodes()` 20 | - $G$ の junction tree のノードを返す.`Node` は `bag` メンバと `ch` メンバを持つ. `bag` はそのノードに含まれる $G$ の頂点, `ch` は junction tree におけるそのノードの子である. 21 | 22 | ## Reference 23 | 24 | - [木幅が2以下のグラフの木分解と動的計画法 - ei1333の日記](https://ei1333.hateblo.jp/entry/2020/02/12/150319) 25 | - [離散最適化基礎論 (2016年度後学期) グラフの木分解](http://dopal.cs.uec.ac.jp/okamotoy/lect/2016/treewidth/) -------------------------------------------------------------------------------- /docs/graph/lowlink.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lowlink 3 | documentation_of: ../../graph/lowlink.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Lowlink はグラフの橋や関節点などを求める際に有効な概念である.グラフの DFS tree において,頂点 $v$ の訪問時刻を `ord[v]` としたとき,$v$ から後退辺 (DFS tree に含まれない辺) を高々1回用いて到達することができる頂点の `ord` の最小値 `low[v]` を lowlink という. 9 | 10 | 辺 $(u, v)$ が橋であることの必要十分条件は `ord[u] < low[v]` が成り立つことである. 11 | 12 | 頂点 $v$ が関節点であることの必要十分条件は 13 | - $v$ が DFS tree の根であり,かつ2つ以上の子を持つ 14 | - $v$ が DFS tree の根ではなく,かつ $v$ のある子 $c$ について `ord[v] <= low[c]` が成り立つ 15 | 16 | のどちらかが成り立つことである. 17 | 18 | 空間計算量: $O(V + E)$ 19 | 20 | ## Operations 21 | 22 | - `Lowlink(vector> G)` 23 | - グラフ $G$ の隣接リストが与えられたとき,$G$ の橋と関節点を求める 24 | - 時間計算量: $O(V + E)$ 25 | - `bool is_bridge(int u, int v)` 26 | - 辺 $uv$ が橋かどうか判定する 27 | - 時間計算量: $O(1)$ 28 | 29 | ## Reference 30 | 31 | - [橋と関節点, lowlink](https://kagamiz.hatenablog.com/entry/2013/10/05/005213) -------------------------------------------------------------------------------- /docs/graph/manhattan_mst.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Manhattan Minimum Spanning Tree 3 | documentation_of: ../../graph/manhattan_mst.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 2次元平面上に点が与えられ,各点の間にそのマンハッタン距離の重みを持つ辺が張られているとき,最小全域木を計算する. 9 | 10 | ## Operations 11 | 12 | - `vector> manhattan_mst(vector> pts)` 13 | - `pts` の点からなるグラフの最小全域木を求める 14 | - 時間計算量: $O(n\log n)$ 15 | 16 | ## Reference 17 | 18 | - [Manhattan Minimum Spanning Tree - 霧でも食ってろ](https://knuu.github.io/manhattan_mst.html) 19 | - [Line Sweep Algorithms - topcoder](https://www.topcoder.com/thrive/articles/Line%20Sweep%20Algorithms) 20 | -------------------------------------------------------------------------------- /docs/graph/maximum_independent_set.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Maximum Independent Set 3 | documentation_of: ../../graph/maximum_independent_set.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 最大独立集合を求める. 9 | 10 | 計算量はよくわからないが,実用上は非常に高速である.$n = 40$ のときに 2 ms 程度で動作する. 11 | 12 | ## Operations 13 | 14 | - `vector maximum_independent_set(vector> G)` 15 | - グラフ $G$ の隣接リストが与えられたとき, $G$ の最大独立集合を求める. 16 | - 時間計算量: $O(n1.466^n)$ -------------------------------------------------------------------------------- /docs/graph/maximum_weight_independent_set.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Maximum Weight Independent Set 3 | documentation_of: ../../graph/maximum_weight_independent_set.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 最大重み独立集合の重みを求める.半分全列挙を用いている. 9 | 10 | ## Operations 11 | 12 | - `T maximum_weight_independent_set(vector> G, vector w)` 13 | - グラフ $G$ の隣接リストと各頂点の重みが与えられたとき, $G$ の最大重み独立集合の重みを求める. 14 | - 時間計算量: $O(n^2 2^{n/2})$ 15 | -------------------------------------------------------------------------------- /docs/graph/minimum_steiner_tree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Minimum Steiner Tree 3 | documentation_of: ../../graph/minimum_steiner_tree.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 最小 Steiner 木は,グラフ $G$ の頂点集合 $S \subset V$ を含む最小の木である. 9 | 10 | 最小 Steiner 木問題は NP 困難である.Dreyfus-Wagner のアルゴリズムを用いて $\vert S\vert$ に関する指数時間で解ける. 11 | 12 | ## Operations 13 | 14 | - `T minimum_steiner_tree(vector>> G, vector terminals)` 15 | - $G$ の `terminals` を含む最小 Steiner 木の重みを求める 16 | - 時間計算量: $O(n3^{k} + (n+m)2^k \log n)\,\text{where}\,k = \vert S\vert$ 17 | 18 | ## Reference 19 | 20 | - [Steiner Tree - My Algorithm](https://kopricky.github.io/code/Academic/steiner_tree.html) 21 | - [指数時間アルゴリズム入門 - slideshare](https://www.slideshare.net/wata_orz/ss-12131479) -------------------------------------------------------------------------------- /docs/graph/mst.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Minimum Spanning Tree Algorithms 3 | documentation_of: ../../graph/mst.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 最小全域木を求めるアルゴリズム詰め合わせ 9 | 10 | ## Kruskal's Algorithm 11 | 12 | Kruskal のアルゴリズムは,無向重み付きグラフの最小全域木を求めるアルゴリズムである. 13 | 14 | - `pair>> kruskal(vector> G, int V)` 15 | - 頂点数 $V$ のグラフ $G$ の辺のリストが与えられたとき,最小全域木とその重みを求める 16 | - 時間計算量: $O(E\log V)$ 17 | 18 | ## Prim's Algorithm 19 | 20 | Prim のアルゴリズムは,無向重み付きグラフの最小全域木を求めるアルゴリズムである. 21 | 22 | - `pair>> prim(vector>> G)` 23 | - グラフ $G$ の隣接リストが与えられたとき,最小全域木とその重みを求める 24 | - 時間計算量: $O(E\log V)$ 25 | 26 | ## Borůvka's Algorithm 27 | 28 | Borůvka のアルゴリズムは,無向重み付きグラフの最小全域木を求めるアルゴリズムである. 29 | 30 | - `pair>> boruvka(vector> G, int V)` 31 | - 頂点数 $V$ のグラフ $G$ の辺のリストが与えられたとき,最小全域木とその重みを求める 32 | - 時間計算量: $O(E\log V)$ -------------------------------------------------------------------------------- /docs/graph/scc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Strongly Connected Components 3 | documentation_of: ../../graph/scc.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | グラフ $G$ の強連結成分分解をする. 9 | 10 | この実装では Kosaraju のアルゴリズムを用いている. 11 | 12 | 強連結成分を一つの頂点に縮約すると,有向非巡回グラフ (DAG) が得られる. 13 | 14 | 強連結成分のラベルはトポロジカル順序になっている. 15 | 16 | ## Operations 17 | 18 | - `vector scc(vector> G)` 19 | - グラフ $G$ の隣接リストが与えられたとき,$G$ を強連結成分分解し,各頂点が属する成分のラベルを返す 20 | - 時間計算量: $O(V + E)$ 21 | - `vector> contract(vector> G, vector comp)` 22 | - グラフ $G$ の隣接リストとその強連結成分が与えられたとき,各強連結成分を縮約したグラフを返す 23 | - 時間計算量: $O(V + E)$ -------------------------------------------------------------------------------- /docs/graph/topological_sort.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Topological Sort 3 | documentation_of: ../../graph/topological_sort.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | トポロジカルソートは,有向非巡回グラフ (DAG) の頂点を順序付けして,任意の辺 $(u, v)$ について $u$ が $v$ よりも前に来るように並べることである. 9 | 10 | ## Operations 11 | 12 | - `vector topological_sort(vector> G)` 13 | - $G$ のトポロジカルソートを返す.$G$ が DAG でないならば,空のリストを返す 14 | - 時間計算量: $O(V + E)$ -------------------------------------------------------------------------------- /docs/graph/two_edge_connected_components.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 2-Edge-Connected Components 3 | documentation_of: ../../graph/two_edge_connected_components.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 二辺連結成分は,どの1本の辺を取り除いても連結であるような部分グラフである.つまり,橋を含まない部分グラフである. 9 | 10 | 二辺連結成分を縮約して得られるグラフは森になっている. 11 | 12 | 空間計算量: $O(V + E)$ 13 | 14 | ## Operations 15 | 16 | - `vector two_edge_connected_components(vector> G, Lowlink low)` 17 | - グラフ $G$ の隣接リストと,$G$ の lowlink 構造体が与えられたとき,$G$ を二辺連結成分分解する 18 | - 時間計算量: $O(V + E)$ 19 | 20 | ## Note 21 | 22 | 縮約には強連結成分分解のファイルにある`contract`関数がそのまま使える. -------------------------------------------------------------------------------- /docs/math/berlekamp_massey.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Berlekamp-Massey Algorithm 3 | documentation_of: ../../math/berlekamp_massey.cpp 4 | --- 5 | 6 | ## Description 7 | 8 | Berlekamp-Massey のアルゴリズムは,与えられた数列を生成する最短の線形漸化式を求めるアルゴリズムである. 9 | 10 | ## Operations 11 | 12 | - `vector berlekamp_massey(vector a)` 13 | - $a$ を生成する最短の線形漸化式を1つ求める 14 | - 時間計算量: $O(n^2)$ 15 | 16 | ## Note 17 | 18 | 漸化式がわからない数列`f`の最初のいくつかを愚直に求めて,Berlekamp-Masseyで漸化式を得て,高速 Kitamasa 法で第`k`項を求めるという暴力的な方法がある. 19 | 20 | ``` 21 | auto coef = berlekamp_massey(f); 22 | f.resize(coef.size()); 23 | reverse(coef.begin(), coef.end()); 24 | auto ans = kitamasa(f, coef, k); 25 | ``` 26 | 27 | 28 | ## Reference 29 | 30 | - [Berlekamp–Massey algorithm](https://en.wikipedia.org/wiki/Berlekamp%E2%80%93Massey_algorithm) 31 | - [Linear Recurrence and Berlekamp-Massey Algorithm](https://codeforces.com/blog/entry/61306?f0a28=1) -------------------------------------------------------------------------------- /docs/math/bostan_mori.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Bostan-Mori Algorithm 3 | documentation_of: ../../math/bostan_mori.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Bostan-Mori algorithm は,$d$ 階線形漸化式の第 $n$ 項を高速に求めるアルゴリズムである. 9 | 10 | ## Operations 11 | 12 | - `T bostan_mori_division(Polynomial p, Polynomial q, long long n)` 13 | - $p(x)/q(x)$ の第 $n$ 項を求める. 14 | - 時間計算量: $O(\mathsf{M}(k) \log n)$, $\mathsf{M(k)}$ は$k$次多項式乗算の計算量 (FFT なら $O(k\log k)$) 15 | - `T bostan_mori_recurrence(vector a, vector c, long long n)` 16 | - 初めの $k$ 項 $a_0, \dots, a_{k-1}$ と漸化式 $a_n = c_0 a_{n-1} + \dots + c_{k-1} a_{n-k}$ によって定まる数列 $(a_n)$ の第 $n$ 項を求める. 17 | - 時間計算量: 同上 18 | 19 | ## Reference 20 | 21 | - [線形漸化的数列のN項目の計算 - Qiita](https://qiita.com/ryuhe1/items/da5acbcce4ac1911f47a) 22 | -------------------------------------------------------------------------------- /docs/math/combination.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Combination 3 | documentation_of: ../../math/combination.cpp 4 | --- 5 | 6 | ## Description 7 | 8 | 階乗 $n!$,組み合わせ $n \choose r$,順列 $_n \mathrm{P} _r$ を法 $mod$ で計算する. 9 | 10 | 空間計算量: $O(n)$ 11 | 12 | ## Operations 13 | 14 | - `Combination(int n)` 15 | - $n$ 以下の整数の階乗及びその逆元を前計算する 16 | - 時間計算量: $O(n)$ 17 | - `T perm(int n, int r)` 18 | - $_n \mathrm{P} _r$ を計算する.$r < 0$ または $n < r$ のときは0を返す 19 | - 時間計算量: $O(1)$ 20 | - `T comb(int n, int r)` 21 | - $n \choose r$ を計算する.$r < 0$ または $n < r$ のときは0を返す 22 | - 時間計算量: $O(1)$ 23 | - `T fact(int n)` 24 | - $n!$ を計算する 25 | - 時間計算量: $O(1)$ 26 | - `T fact_inv(int n)` 27 | - $n!$ の逆元を計算する 28 | - 時間計算量: $O(1)$ 29 | 30 | 以下の関数は`Combination`クラスに含まれない 31 | 32 | - `T comb(int n, int r)` 33 | - $n \choose r$ を計算する. 34 | - 時間計算量: $O(r)$ -------------------------------------------------------------------------------- /docs/math/combination_arbitrary_mod.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Combination (Arbitrary mod) 3 | documentation_of: ../../math/combination_arbitrary_mod.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 二項係数を任意の mod で計算する. 9 | 10 | - `vector combination_arbitrary_mod(int n)` 11 | - $\binom{n}{k}\quad (k=0,\dots,n)$ を mod $m$ で計算する 12 | - 時間計算量: $O(n\log m / \log\log m)$ 13 | 14 | ## Reference 15 | 16 | - [任意 mod で二項係数を列挙する](https://qiita.com/suisen_cp/items/d0ab7e728b98bbec818f) 17 | - verify: [https://atcoder.jp/contests/abc281/submissions/37229804](https://atcoder.jp/contests/abc281/submissions/37229804) -------------------------------------------------------------------------------- /docs/math/convert_base.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Base Conversion 3 | documentation_of: ../../math/convert_base.cpp 4 | --- 5 | 6 | ## Description 7 | 8 | 10進数の整数 $n$ を $base$ 進数に変換する 9 | 10 | ## Operations 11 | 12 | - `vector convert_base(int n, int base)` 13 | - 時間計算量: $O(\log_{base} n)$ -------------------------------------------------------------------------------- /docs/math/count_subset_sum.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Count Subset Sum 3 | documentation_of: ../../math/count_subset_sum.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 各 $v=1,2,\dots,V$ に対して,与えられた数列の部分列であって総和が $v$ であるものの個数を数える. 9 | 10 | ## Operations 11 | 12 | - `vector count_subset_sum(vector val, int V)` 13 | - 各 $v=1,2,\dots,V$ に対して,総和 $v$ の部分列の個数を数える 14 | - 時間計算量: $O(n\log n)$ 15 | -------------------------------------------------------------------------------- /docs/math/factorial.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Factorial 3 | documentation_of: ../../math/factorial.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | $n! \pmod m$ を計算する 9 | 10 | 空間計算量: $O(\sqrt{m} \log m)$ 11 | 12 | ## Operations 13 | 14 | - `Factorial()` 15 | - 前計算を行う 16 | - 時間計算量: $O(\sqrt{m} (\log m)^2)$ 17 | - `mint query(int m)` 18 | - $n! \pmod m$ を計算する 19 | - 時間計算量: $O(\sqrt{m})$ 20 | 21 | ## Reference 22 | 23 | - [Multipoint Evaluation の アルゴリズム - 37zigenのHP](https://37zigen.com/multipoint-evaluation/) -------------------------------------------------------------------------------- /docs/math/interpolation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Polynomial Interpolation 3 | documentation_of: ../../math/interpolation.cpp 4 | --- 5 | 6 | ## Description 7 | 8 | 多項式補間をする. 9 | 10 | ## Operations 11 | 12 | - `Polynomial interpolate(vector x, vector y)` 13 | - 与えられた点の補間多項式を計算する 14 | - 時間計算量: $O(n^2)$ -------------------------------------------------------------------------------- /docs/math/kitamasa.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Kitamasa's Algorithm 3 | documentation_of: ../../math/kitamasa.cpp 4 | --- 5 | 6 | ## Description 7 | 8 | Kitamasa 法は,$d$ 階線形漸化式の第 $n$ 項を高速に求めるアルゴリズムである. 9 | 10 | ## Operations 11 | 12 | - `T kitamasa(vector a, vector c, long long n)` 13 | - 初めの $d$ 項 $a_0, \dots, a_{d-1}$ と漸化式 $a_n = c_0 a_{n-d} + \dots + c_{d-1} a_{n-1}$ によって定まる数列 $(a_n)$ の第 $n$ 項を求める. 14 | - 時間計算量: $O(d^2 \log n)$ 15 | 16 | ## Reference 17 | 18 | - [きたまさ法メモ](https://yosupo.hatenablog.com/entry/2015/03/27/025132) -------------------------------------------------------------------------------- /docs/math/lagrange_interpolation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lagrange Interpolation 3 | documentation_of: ../../math/lagrange_interpolation.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Lagrange 補間は,$d+1$ 点が与えられたときにそれらを通る$d$次以下の多項式を求めるアルゴリズムである.この多項式は一意に定まる. 9 | 10 | ## Operations 11 | 12 | - `T lagrange_interpolation(vector f, long long n)` 13 | - $f(0),f(1),\dots,f(d)$ が与えられたときに,$f(n)$を求める 14 | - 時間計算量: $O(d)$ 15 | 16 | ## Reference 17 | 18 | - [ABC208 F - Cumulative Sum 解説](https://atcoder.jp/contests/abc208/editorial/2195) 19 | - verify: [https://atcoder.jp/contests/abc208/submissions/30592769](https://atcoder.jp/contests/abc208/submissions/30592769) -------------------------------------------------------------------------------- /docs/math/lagrange_polynomial.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lagrange Polynomial 3 | documentation_of: ../../math/lagrange_polynomial.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Lagrange 多項式は,与えられた $d+1$ 点を通る $d$ 次以下の多項式である.この多項式は存在すれば一意に定まる. 9 | 10 | ## Operations 11 | 12 | - `Polynomial lagrange_polynomial(vector x, vector y)` 13 | - $(x_i,y_i)\,(i=0,1,\dots,n)$ を通る Lagrange 多項式を求める 14 | - 時間計算量: $O(n (\log n)^2)$ 15 | 16 | ## Reference 17 | 18 | - [多項式補間:アルゴリズム](https://37zigen.com/lagrange-interpolation/) 19 | -------------------------------------------------------------------------------- /docs/math/linalg/characteristic_polynomial.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Characteristic Polynomial 3 | documentation_of: ../../../math/linalg/characteristic_polynomial.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 正方行列の特性多項式を求める. 9 | 10 | ## Operations 11 | 12 | - `Polynomial characteristic_polynomial(SquareMatrix mat)` 13 | - 与えられた正方行列の特性多項式を求める 14 | - 時間計算量: $O(n^3)$ 15 | 16 | ## Reference 17 | 18 | - [R. Rehman and I. Ipsen, La Budde's Method for Computing Characteristic Polynomials, https://arxiv.org/abs/1104.3769](https://arxiv.org/abs/1104.3769) 19 | - [Characteristic Polynomial / $\det(M_0+xM_1)$ - competitive-programming-library](https://rniya.github.io/competitive-programming-library/src/matrix/characteristic_polynomial.hpp.html) -------------------------------------------------------------------------------- /docs/math/linalg/hafnian.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hafnian 3 | documentation_of: ../../../math/linalg/hafnian.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 偶数次対称行列のハフニアンを求める. $2n \times 2n$ 対称行列 $A$ のハフニアンは次式で定義される. 9 | $$ 10 | \operatorname{haf}(A) = \sum_{\rho \in P_{2n}^2} \prod_{\{i,j\} \in \rho} A_{i,j} 11 | $$ 12 | ここで, $P_{2n}^n$ は $\{1,2,\dots,2n\}$ の大きさ $2$ の部分集合への分割の全体である. 13 | 14 | これは, $A$ を隣接行列として持つ無向グラフの完全マッチングの個数である. 15 | 16 | ## Operations 17 | 18 | - `T hafnian(vector> mat)` 19 | - 与えられた偶数次対称行列のハフニアンを求める 20 | - 時間計算量: $O(n^2 2^{n/2})$ 21 | 22 | ## Reference 23 | 24 | - [Hafnian of Matrix - @tko919, HackMD](https://hackmd.io/@tko919/HyTPhjWco) 25 | - [集合べき級数関連 (4) 問題例 - maspyのHP](https://maspypy.com/%e9%9b%86%e5%90%88%e3%81%b9%e3%81%8d%e7%b4%9a%e6%95%b0%e9%96%a2%e9%80%a3-4-%e5%95%8f%e9%a1%8c%e4%be%8b) -------------------------------------------------------------------------------- /docs/math/linalg/system_of_linear_equations.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: System of Linear Equations 3 | documentation_of: ../../../math/linalg/system_of_linear_equations.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 連立一次方程式を解く. 9 | 10 | ## Operations 11 | 12 | - `vector> solve_system(Matrix A, vector b)` 13 | - $Ax = b$ の解を返す.返り値を `sol` としたとき,`sol[0]` は解の1つ,`sol[1:]` は解空間の基底である.解がないときは空リストを返す. 14 | - 時間計算量: $O(mn^2)$ 15 | -------------------------------------------------------------------------------- /docs/math/multipoint_evaluation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Multipoint Evaluation 3 | documentation_of: ../../math/multipoint_evaluation.cpp 4 | --- 5 | 6 | ## Description 7 | 8 | 多点評価は,与えられた $m$ 点での多項式の値を評価する問題である. 9 | 10 | ## Operations 11 | 12 | - `vector multipoint_evaluation(Polynomial p, vector x)` 13 | - $p(x_1),p(x_2),\dots,p(x_m)$ の値を評価する 14 | - 時間計算量: $O(m(\log m)^2+n\log n)$ 15 | 16 | ## Reference 17 | 18 | - [Multipoint Evaluation の アルゴリズム - 37zigenのHP](https://37zigen.com/multipoint-evaluation/) -------------------------------------------------------------------------------- /docs/math/number-theory/carmichael.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Carmichael Function 3 | documentation_of: ../../../math/number-theory/carmichael.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Carmichael 関数 $\lambda(n)$ の値を求める.これは,$n$ と互いに素である $n$ 以下の自然数 $a$ 全てに対して$a^m \equiv 1 \mod n$ を満たすような最小の自然数 $m$ を与える. 9 | 10 | Euler の定理より $m = \phi(n)$ は上の条件を満たすが,それが最小の $m$ であるとは限らない.最小の $m$ が $\lambda(n)$ である. 11 | 12 | ## Operations 13 | 14 | - `long long carmichael(long long n)` 15 | - $\lambda(n)$ を求める 16 | - 時間計算量: $O(\sqrt{n})$ -------------------------------------------------------------------------------- /docs/math/number-theory/divisor.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Divisor 3 | documentation_of: ../../../math/number-theory/divisor.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | $n$ の約数を試し割り法で全て求める. 9 | 10 | ## Operations 11 | 12 | - `vector divisor(long long n)` 13 | - $n$ の約数を昇順で返す 14 | - 時間計算量: $O(\sqrt{n})$ -------------------------------------------------------------------------------- /docs/math/number-theory/extgcd.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Extended Euclidean Algorithm 3 | documentation_of: ../../../math/number-theory/extgcd.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 拡張 Euclid の互除法は,2変数1次不定方程式 $ax + by = \gcd(a, b)$ の解 $(x, y)$ を1組求めるアルゴリズムである. 9 | 10 | また,これを利用して,与えられた整数 $a$ の法 $mod$ での逆元を求めることができる.Fermat の小定理を利用したアルゴリズムより制約が少なく定数倍高速であるため,基本的にこちらを用いる. 11 | 12 | - `pair extgcd(long long a, long long b)` 13 | - $ax + by = \gcd(a, b)$ の解 $(x, y)$ を1組求める 14 | - 時間計算量: $O(\log \min(a, b))$ 15 | - `long long mod_inv(long long a, long long mod)` 16 | - $a$ の法$mod$での逆元を求める -------------------------------------------------------------------------------- /docs/math/number-theory/fast_prime.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Fast Prime Number Algorithms 3 | documentation_of: ../../../math/number-theory/fast_prime.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 素数に関する高速なアルゴリズム 9 | 10 | ## Primality Test 11 | 12 | $n$ を Miller-Rabin 法で素数判定する. 13 | 14 | - `bool is_prime(long long n)` 15 | - $n$ を素数判定する 16 | - 時間計算量: $O(\log^3 n)$ 17 | 18 | ## Prime Factorization 19 | 20 | $n$ を Pollard's rho 法で素因数分解する. 21 | 22 | - `vector prime_factor(long long n)` 23 | - $n$ の素因数のリストを返す 24 | - 時間計算量: $\mathrm{expected}\ O(n^{\frac{1}{4}} \log n)$ -------------------------------------------------------------------------------- /docs/math/number-theory/floor_sum.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Sum of Floor of Linear 3 | documentation_of: ../../../math/number-theory/floor_sum.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 一次関数の床関数の和 $\sum_{i=0}^{N-1} \left\lfloor \frac{Ai + B}{M} \right\rfloor$ を再帰的に計算する. 9 | 10 | 計算量はユークリッドの互除法と同様に対数時間となるが,どの変数に依存するのかはよくわかっていない (僕が理解していない). 11 | 12 | - `long long floor_sum(long long n, long long m, long long a, long long b)` 13 | - $\sum_{i=0}^{N-1} \left\lfloor \frac{Ai + B}{M} \right\rfloor$ を計算する -------------------------------------------------------------------------------- /docs/math/number-theory/garner.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Garner's Algorithm 3 | documentation_of: ../../../math/number-theory/garner.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Garner のアルゴリズムは,連立合同式 $x \equiv b_i \mod m_i \quad (i=1,\dots,n)$ の解を求めるアルゴリズムである. 9 | 10 | $m_i$が pairwise coprime であるとき,この連立合同式には法$m = m_1\dots m_n$のもとでただ一つの解が存在することが中国の剰余定理によって保証される. 11 | 12 | ## Operations 13 | 14 | - `long long garner(vector b, vector m, long long mod)` 15 | - 連立合同式を満たす最小の非負整数を法$mod$で求める. 16 | - 時間計算量: $O(n^2)$ 17 | 18 | 19 | ## Reference 20 | 21 | - [中国剰余定理 (CRT) の解説と、それを用いる問題のまとめ](https://qiita.com/drken/items/ae02240cd1f8edfc86fd) 22 | - [Chinese Remainder Theorem](https://cp-algorithms.com/algebra/chinese-remainder-theorem.html) -------------------------------------------------------------------------------- /docs/math/number-theory/moebius.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Möbius Function 3 | documentation_of: ../../../math/number-theory/moebius.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Möbius 関数 $\mu(n)$ は次のように定義される: 9 | - $\mu(n) = 0$ ($n$ が平方因子を持つとき) 10 | - $\mu(n) = (-1)^k$ ($n$ の素因数が $k$ 個のとき) 11 | 12 | ## Operations 13 | 14 | - `int moebius(long long n)` 15 | - $\mu(n)$ を求める 16 | - 時間計算量: $O(\sqrt{n})$ 17 | - `vector moebius_table(n)` 18 | - $n$ 以下の正整数 $i$ について $\mu(i)$ を求める 19 | - 時間計算量: $O(n \log\log n)$ 20 | - `pair, vector> mertens_table(long long n)` 21 | - 自然数 $1\leq i \leq N$ を用いて $k=\lfloor \frac{n}{i} \rfloor$ と表される各自然数について,Mertens 関数 $M(k)=\sum_{j=1}^k \mu(j)$ を求める 22 | - vector の組 `(small, large)` を返す.`small[i]` は $M(i)$, `large[i]` は $M(\lfloor \frac{n}{i} \rfloor)$ である. 23 | - 時間計算量: $O(n^{2/3}(\log\log n)^{1/3})$ -------------------------------------------------------------------------------- /docs/math/number-theory/prime.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Prime Number Algorithms 3 | documentation_of: ../../../math/number-theory/prime.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 素数に関するアルゴリズム詰め合わせ 9 | 10 | ## Primality Test 11 | 12 | $n$ を試し割り法で素数判定する. 13 | 14 | - `bool is_prime(long long n)` 15 | - $n$ を素数判定する 16 | - 時間計算量: $O(\sqrt{n})$ 17 | 18 | ## Prime Table 19 | 20 | エラトステネスの篩を用いて,$n$ 以下の整数の素数表を構築する. 21 | 22 | - `vector prime_table(int n)` 23 | - $n$ 以下の整数の素数表を構築する 24 | - 時間計算量: $O(n\log\log n)$ 25 | 26 | ## Table of Minimum Prime Factors 27 | 28 | エラトステネスの篩を用いて,$n$ 以下の整数のそれぞれについてその最小の素因数を計算する. 29 | 30 | - `vector min_factor_table(int n)` 31 | - $n$ 以下の各整数の最小の素因数を計算する 32 | - 時間計算量: $O(n\log\log n)$ 33 | 34 | ## Prime Factorization 35 | 36 | $n$ を試し割り法で素因数分解する. 37 | 38 | - `map prime_factor(long long n)` 39 | - $n$ を素因数分解し,素因数とその個数を返す. 40 | - 時間計算量: $O(\sqrt{n})$ -------------------------------------------------------------------------------- /docs/math/number-theory/prime_count.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Prime Counting Function 3 | documentation_of: ../../../math/number-theory/prime_count.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 素数計数関数 $\pi(n)$ を計算する. 9 | 10 | - `long long prime_count(long long n)` 11 | - $n$ 以下の素数の個数を計算する 12 | - 時間計算量: $O(n^{3/4}/\log n)$ 13 | 14 | ## Reference 15 | 16 | - [眠れない夜は素数の個数でも数えましょう](https://rsk0315.hatenablog.com/entry/2021/05/18/015511) -------------------------------------------------------------------------------- /docs/math/number-theory/primitive_root.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Primitive Root 3 | documentation_of: ../../../math/number-theory/primitive_root.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 素数 $p$ を法とする原子根を求める. 9 | 10 | - `long long primitive_root(long long p)` 11 | - 素数 $p$ を法とする原子根を求める 12 | - 時間計算量: $\mathrm{expected}\ O(n^{\frac{1}{4}} \log n)$ 13 | 14 | ## Reference 15 | 16 | - [原子根のアルゴリズム - 37zigenのHP](https://37zigen.com/primitive-root/) -------------------------------------------------------------------------------- /docs/math/number-theory/stern_brocot_tree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Stern-Brocot Tree 3 | documentation_of: ../../../math/number-theory/stern_brocot_tree.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Stern-Brocot tree は,有理数の探索に用いられる二分木である. 9 | 10 | ## Operations 11 | 12 | - `pair, pair> stern_brocot_tree_search(long long n, F cond)` 13 | - 分母及び分子が $n$ 以下の既約分数 $p/q$ のうち,条件 $\mathrm{cond}(p/q)$ を満たす最大のもの $a/b$ と満たさない最小のもの $c/d$ を返す. $\mathrm{cond}(p/q)$ の単調性を仮定する. 14 | - 時間計算量: $O(f(n)\log n)$, $f(n)$ は $\mathrm{cond}(p/q)$ の計算量 15 | 16 | 17 | ## Reference 18 | 19 | - [ABC294 F - Sugar Water 2 解説](https://atcoder.jp/contests/abc294/editorial/6017) 20 | - verify: [https://yukicoder.me/submissions/857736](https://yukicoder.me/submissions/857736) -------------------------------------------------------------------------------- /docs/math/partition_function.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Partition Function 3 | documentation_of: ../../math/partition_function.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 非負整数 $n$ に対し,分割数 $p(n)$ とは, $n$ を順番の違いを除いて正整数の総和として表す方法の総数である. 9 | 10 | 分割数 $p(n)$ の母関数は次式で与えられる. 11 | 12 | $$ 13 | \sum_{n=0}^\infty p(n)x^n = \prod_{k=1}^\infty \frac{1}{1-x^k} 14 | $$ 15 | 16 | 右辺の分母は, Euler の五角数定理によって高速に計算できる. 17 | 18 | ## Operations 19 | 20 | - `Polynomial partition_function_table(int n)` 21 | - $p(k)$ を各 $k=0,1,\dots,n$ について計算する 22 | - 時間計算量: $O(n\log n)$ 23 | -------------------------------------------------------------------------------- /docs/math/q_analogs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: q-Analogs 3 | documentation_of: ../../math/q_analogs.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | $q$-数, $q$-階乗, $q$-二項係数を計算する. 9 | 10 | 空間計算量: $O(n)$ 11 | 12 | ## Operations 13 | 14 | - `qAnalogs(mint q, int n)` 15 | - $n$ 以下の非負整数の $q$-数, $q$-階乗及びその逆元を前計算する 16 | - 時間計算量: $O(n)$ 17 | - `T number(int n)` 18 | - $[n]_q$ を返す 19 | - 時間計算量: $O(1)$ 20 | - `T fact(int n)` 21 | - $[n]_q!$ を返す 22 | - 時間計算量: $O(1)$ 23 | - `T fact_inv(int n)` 24 | - $[n]_q!$ の逆元を返す 25 | - 時間計算量: $O(1)$ 26 | - `T binom(int n, int k)` 27 | - $\binom{n}{k}_q$ を返す 28 | - 時間計算量: $O(1)$ 29 | 30 | ## Reference 31 | 32 | - [ABC278 Ex - make 1 解説](https://atcoder.jp/contests/abc278/editorial/5210) 33 | - verify: [https://atcoder.jp/contests/abc278/submissions/49047601](https://atcoder.jp/contests/abc278/submissions/49047601) -------------------------------------------------------------------------------- /docs/math/set/subset_convolution.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Subset Convolution 3 | documentation_of: ../../../math/set/subset_convolution.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 数列 $f$ と $g$ の subset convolution $f * g$ は以下で定義される. 9 | 10 | $$ 11 | (f * g)(S) = \sum_{T \subset S} f(T) g(S\setminus T) 12 | $$ 13 | 14 | $f, g$ の長さを $2^n$ とするとき,素朴に部分集合を列挙する方法では計算量は $O(3^n)$ となるが,$O(n^2 2^n)$ で計算することができる. 15 | 16 | ## Operations 17 | 18 | - `vector subset_convolution(vector a, vector b)` 19 | - 数列 $a$ と $b$ の subset convolution を計算する 20 | - 時間計算量: $O(n^2 2^n)$ 21 | 22 | ## Reference 23 | 24 | - [Subset Convolutionのアルゴリズム - 37zigenのHP](https://37zigen.com/subset-convolution/) -------------------------------------------------------------------------------- /docs/math/stirling_first.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Stirling Number of the First Kind 3 | documentation_of: ../../math/stirling_first.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 第1種 Stirling 数 $s(n,k)$ は,以下の恒等式で定義される数である. 9 | 10 | $$ 11 | x(x-1)\cdots(x-(n-1)) = \sum_{k=0}^n s(n,k) x^k 12 | $$ 13 | 14 | $s(n,k)$ の絶対値 (${n \brack k}$ と書く) は,$n$ 要素の置換のうち,$k$ 個のサイクルに分解されるものの個数である. 15 | 16 | ## Operations 17 | 18 | - `vector stirling_first_table(int n)` 19 | - $s(n,k)$ を各 $k=0,1,\dots,n$ について計算する 20 | - 時間計算量: $O(n\log n)$ 21 | 22 | ## Notes 23 | 24 | 第1種 Stirling 数について以下の式が成り立つ. 25 | 26 | $$ 27 | s(n,k) = (-1)^{(n-k)} {n \brack k} 28 | $$ 29 | 30 | $$ 31 | {n\brack k} = {n-1\brack k-1} + (n-1){n-1 \brack k} 32 | $$ 33 | 34 | ## Reference 35 | 36 | - [「写像12相」を総整理! 〜 数え上げ問題の学びの宝庫 〜 - Qiita](https://qiita.com/drken/items/f2ea4b58b0d21621bd51) 37 | 38 | -------------------------------------------------------------------------------- /docs/misc/intervals.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Intervals 3 | documentation_of: ../../misc/intervals.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 整数の閉区間を管理する. 9 | 10 | 機能的には range update point get の双対セグメント木の上位互換である (`long long` 型の座標を扱える + 区間の列挙が可能である). 11 | 12 | ## Operations 13 | 14 | - `Intervals(T default_val)` 15 | - デフォルトの値 `default_val` を受け取り,初期化する 16 | - `T get(X x)` 17 | - 点 $x$ での値を返す 18 | - 時間計算量: $O(\log n)$ 19 | - `vector> get(X l, X r)` 20 | - 区間 $[l, r]$ と交わる区間を返す 21 | - 時間計算量: $O(k\log n)$, $k$ は $[l, r]$ と交わる区間の数 22 | - `void set(X l, X y, T v)` 23 | - 区間 $[l, r]$ の値を $v$ に更新する. 24 | - 時間計算量: $\mathrm{amortized}\ O(\log n)$ 25 | - `void erase(X l, X r)` 26 | - 区間 $[l, r]$ の値をデフォルトの値に戻す 27 | - 時間計算量: $\mathrm{amortized}\ O(\log n)$ -------------------------------------------------------------------------------- /docs/misc/majority.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Boyer-Moore Majority Vote Algorithm 3 | documentation_of: ../../misc/majority.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 数列の過半数を占める要素を求める. 9 | 10 | - `optional majority(vector v)` 11 | - 数列 `v` の過半数を占める要素を求める 12 | - 時間計算量: $O(n)$ 13 | 14 | ## Reference 15 | 16 | - [Boyer–Moore majority vote algorithm - Wikipedia](https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_majority_vote_algorithm) 17 | - verify: [https://atcoder.jp/contests/abc272/submissions/35557503](https://atcoder.jp/contests/abc272/submissions/35557503) 18 | -------------------------------------------------------------------------------- /docs/misc/mo.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Mo's Algorithm 3 | documentation_of: ../../misc/mo.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Mo のアルゴリズム (クエリ平方分割) は,静的な列に対するクエリをオフラインで高速に処理するアルゴリズムである. 9 | 10 | ## Operations 11 | 12 | - `Mo(int n)` 13 | - 長さ $n$ の列に対するクエリを処理する 14 | - 時間計算量: $O(1)$ 15 | - `void query(int l, int r)` 16 | - 区間 $[l, r)$ に対してクエリをする 17 | - 時間計算量: $O(1)$ 18 | - `void run(ExL exl, ShL shl, ExR exr, ShR shr, Out out)` 19 | - 以下の関数を引数に取り,クエリを実行する 20 | - `exl`: 区間を左に1マス伸ばしたときの状態を更新する 21 | - `shl`: 区間を左に1マス縮めたときの状態を更新する 22 | - `exr`: 区間を右に1マス伸ばしたときの状態を更新する 23 | - `shr`: 区間を右に1マス縮めたときの状態を更新する 24 | - `out`: $i$ 番目のクエリの結果を計算する 25 | - 時間計算量: $O(f(n)n\sqrt{n})$, $f(n)$ は状態の更新にかかる計算量 26 | -------------------------------------------------------------------------------- /docs/misc/sorting.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Sorting Algorithms 3 | documentation_of: ../../misc/sorting.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | いくつかのソーティングアルゴリズムの実装.主にインタラクティブ問題での使用を想定しており,時間計算量よりも比較回数を重視している. 9 | 10 | - `void merge_sort(vector arr, int l, int r, Compare cmp)` 11 | - リスト $\mathrm{arr}$ の区間 $[l, r)$ を比較関数 $\mathrm{cmp}$ によってマージソートする 12 | - 時間計算量: $O(n \log n)$ 13 | - `void merge_insertion_sort(vector arr, Compare cmp)` 14 | - 要素に重複のないリスト $\mathrm{arr}$ を比較関数 $\mathrm{cmp}$ によってソートする 15 | - 時間計算量: $O(n^2 \log n)$ ($O(n (\log n)^2)$ に高速化可能) 16 | 17 | ## Note 18 | 19 | 比較ソートの最悪比較回数の情報理論的下界は $\lceil \log_2 n! \rceil \approx n\log_2 n - 1.443 n$ 回である. 20 | 21 | マージソートの最悪比較回数は $n\log_2 n-0.915n$ から $n\log_2 n-n$ の間になることが知られている. 22 | 23 | マージ挿入ソートの最悪比較回数は $n\log_2 n-1.415n$ 程度であることが知られている.マージ挿入ソートは,最悪比較回数が情報理論的下界に最も近いソーティングアルゴリズムの一つである. -------------------------------------------------------------------------------- /docs/misc/stable_matching.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Stable Matching 3 | documentation_of: ../../misc/stable_matching.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | (男性最適) 安定マッチングを返す. 9 | 10 | $n$ 人の男性と $n$ 人の女性がいる状況を考える.各人は異性に対して選好順序を持っている.このとき,安定マッチングとは,$n$ 組の男女のマッチングであって,互いに現在組んでいる相手よりもお互いのことが好きであるような男女のペア (ブロッキングペア) が存在しないようなものである. 11 | 12 | どの男性も安定マッチングでペアになれる女性のうち,もっとも好きな女性とペアになっているような安定マッチングを男性最適安定マッチングと言う.男性最適安定マッチングは Gale-Shapley アルゴリズムによって $O(n^2)$ 時間で求めることができる. 13 | 14 | ## Operations 15 | 16 | - `vector stable_matching(vector> man, vector> woman)` 17 | - 男性と女性の各人の選好順序が与えられたとき,(男性最適) 安定マッチングの1つにおいて,各女性と婚約している男性を返す. 18 | - 時間計算量: $O(n^2)$ 19 | 20 | 21 | ## Reference 22 | 23 | - [Stable marriage problem - Wikipedia](https://en.wikipedia.org/wiki/Stable_marriage_problem) 24 | - [Gale-Shapley algorithm - Wikipedia](https://en.wikipedia.org/wiki/Gale%E2%80%93Shapley_algorithm) 25 | -------------------------------------------------------------------------------- /docs/sat/twosat.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 2-SAT 3 | documentation_of: ../../sat/twosat.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 2-SAT は,節内のリテラル数が高々2つであるような乗法標準形の論理式に対する充足可能性問題 (SAT) である. 9 | 10 | 節 $(u \lor v)$ が $(\lnot u \rightarrow v) \land (\lnot v \rightarrow u)$ と同値であることを利用すると,2-SAT を強連結成分分解を用いて解くことができる. 11 | 12 | ## Operations 13 | 14 | - `vector two_sat(int n, vector> clauses)` 15 | - $n$ リテラルを含む節のリストが与えられた時,すべての節を充足するリテラルの真偽値の組み合わせを一つ返す.節は `{i, f, j, g}` の形で与え,$((x_i = f) \lor (x_j = g))$ を追加する.問題が充足可能でない場合,空リストを返す. 16 | - 時間計算量: $O(n)$ -------------------------------------------------------------------------------- /docs/string/enumerate_runs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Enumerate Runs 3 | documentation_of: ../../string/enumerate_runs.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 文字列の run (部分文字列の繰り返しであって,長さが極大のもの) を列挙する.この実装では Main-Lorentz アルゴリズムを用いている. 9 | 10 | ## Operations 11 | 12 | - `vector> enumerate_runs(string s)` 13 | - 文字列 $s$ の run を列挙する.`ret[p]` には周期 $p$ の run が含まれている. 14 | - 時間計算量: $O(n\log n)$ 15 | 16 | ## Reference 17 | 18 | - [Runの列挙 (Main-Lorentz algorithm)](https://pazzle1230.hatenablog.com/entry/2019/11/27/234632) 19 | -------------------------------------------------------------------------------- /docs/string/lcp_array.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Longest Common Prefix Array 3 | documentation_of: ../../string/lcp_array.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 高さ配列 (LCP array) は,接尾辞配列における隣同士の接尾辞で,先頭何文字が共通しているかを表す配列である.`lcp[i]` は接尾辞 `s[sa[i]..]` と接尾辞 `s[sa[i + 1]..]` の先頭で共通している文字数になる. 9 | 10 | ## Operations 11 | 12 | - `vector lcp_array(string s, SuffixArray sa)` 13 | - 文字列 `s` と `s` の接尾辞配列 `sa` から高さ配列を構築する 14 | - 時間計算量: $O(n)$ -------------------------------------------------------------------------------- /docs/string/lyndon_factorization.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lyndon Factorization 3 | documentation_of: ../../string/lyndon_factorization.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Lyndon word とは,その任意の proper suffix よりも辞書順で真に小さいような文字列である. 9 | 10 | 任意の文字列は,単調非増加な Lyndon word の結合として一意的に分解される.この分解を Lyndon factorization という. 11 | 12 | ## Operations 13 | 14 | - `vector lyndon_factorization(string s)` 15 | - 文字列 $s$ を Lyndon factorization したときの,各 Lyndon word の最初の index を返す 16 | - 時間計算量: $O(n)$ 17 | 18 | ## Reference 19 | 20 | - [Lyndon factorization - Algorithms for Competitive Programming](https://cp-algorithms.com/string/lyndon_factorization.html) -------------------------------------------------------------------------------- /docs/string/manacher.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Manacher's Algorithm 3 | documentation_of: ../../string/manacher.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Manacher のアルゴリズムは,文字列中の回文である部分文字列を求めるアルゴリズムである. 9 | 10 | 返り値を$A$とする.$S_i$を中心とする最大の回文の長さを$x$とすると,$A[2i] = (x + 1) / 2$.$S_iS_{i+1}$を中心とする最大の回文の長さを$x$とすると,$A[2i + 1] = x / 2$. 11 | 12 | - `vector manacher(string s)` 13 | - Manacher のアルゴリズムを実行する 14 | - 時間計算量: $O(n)$ 15 | 16 | ## Reference 17 | 18 | - [Manacher's Algorithm - Finding all sub-palindromes in O(N)](https://cp-algorithms.com/string/manacher.html) -------------------------------------------------------------------------------- /docs/string/palindromic_tree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Palindromic Tree 3 | documentation_of: ../../string/palindromic_tree.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Palindromic Tree は,文字列の回文の情報を保持するデータ構造である. 9 | 10 | ## Operations 11 | 12 | - `void add(char c)` 13 | - 文字 $c$ を現在の文字列の末尾に追加する 14 | - 時間計算量: $\mathrm{amortized}\ O(1)$ 15 | - `vector get_suffix_palindromes()` 16 | - 現在の文字列の suffix である回文の長さを列挙する 17 | - 時間計算量: $O(k)$, $k$ は回文の個数 18 | - `vector> get_palindrome_frequencies()` 19 | - 文字列の相異なる回文部分文字列の位置と長さと個数を列挙する.破壊的. 20 | - 時間計算量: $O(n)$ 21 | 22 | ## Reference 23 | 24 | - [Palindromic Tree - slideshare](https://www.slideshare.net/__math/palindromic-tree) 25 | 26 | 27 | -------------------------------------------------------------------------------- /docs/string/pattern_search_2d.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 2D Pattern Search (Baker-Bird Algorithm) 3 | documentation_of: ../../string/pattern_search_2d.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 2次元のテキストから長方形のパターンを探索する. 9 | 10 | ## Operations 11 | 12 | - `vector> pattern_search_2d(vector txt, vector pat)` 13 | - `txt` 中の `pat` の出現位置 (左上) を列挙する 14 | - 時間計算量: $O(HW + RC)$, $H \times W$ は `txt` のサイズ,$R \times C$ は `pat` のサイズ 15 | 16 | ## Reference 17 | 18 | - [Aho-Corasick で 2 次元パターンマッチング - tobya's blog](https://tobya.hatenablog.com/entry/2017/12/20/223629) 19 | -------------------------------------------------------------------------------- /docs/string/suffix_array.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Suffix Array 3 | documentation_of: ../../string/suffix_array.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 接尾辞配列 (suffix array) は,文字列のインデックスを接尾辞の辞書順に並べたものである.文字列検索が効率的に行える. 9 | 10 | この実装では Manber-Myers のアルゴリズムを用いている.ソートに基数ソートを用いることで時間計算量を $O(n\log^2 n)$ から $O(n\log n)$ に改善している. 11 | 12 | なお,SA-IS という $O(n)$ のアルゴリズムもある (未実装). 13 | 14 | ## Operations 15 | 16 | - `vector suffix_array(string s)` 17 | - `s` の接尾辞配列を構築する 18 | - 時間計算量: $O(n\log n)$ 19 | 20 | ## Reference 21 | 22 | - [Suffix Array](https://cp-algorithms.com/string/suffix-array.html) -------------------------------------------------------------------------------- /docs/string/trie.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Trie 3 | documentation_of: ../../string/trie.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | トライ木は,文字列の集合を管理するデータ構造である. 9 | 10 | トライ木は実現したい処理に応じて,関数や持たせるデータを自分で書くことが多いので,これはあくまでテンプレ. 11 | 12 | ## Operations 13 | 14 | - `void insert(string s, int id)` 15 | - 文字列 $s$ を挿入する 16 | - 時間計算量: $O(\vert s\vert)$ 17 | - `void compress()` 18 | - トライ木を圧縮して Patricia trie を構築する.これにより,木の木の深さが $O(\sqrt{\sum \vert s \vert})$ になる. 19 | - 時間計算量: $O(\sum \vert s\vert)$ -------------------------------------------------------------------------------- /docs/string/z_array.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Z Array 3 | documentation_of: ../../string/z_array.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Z array は,文字列 `S` と `S[i:]` の最長共通接頭辞の長さを表す配列である.Z array を求めるアルゴリズムは Z algorithm と呼ばれる. 9 | 10 | Z array を用いると文字列中のパターンをすべて検索することができる.文字列を `S`,パターンを `P` とし,`P$S` (`$` は `S` にも `P` にも含まれない文字) の Z array を構築すると,値が `P` の長さと一致するところで `P` が現れる. 11 | 12 | ## Operations 13 | 14 | - `vector z_array(string s)` 15 | - Z array を構築する 16 | - 時間計算量: $O(n)$ 17 | 18 | ## Reference 19 | 20 | - [Z algorithm (Linear time pattern searching Algorithm)](https://www.geeksforgeeks.org/z-algorithm-linear-time-pattern-searching-algorithm/) -------------------------------------------------------------------------------- /docs/tree/auxiliary_tree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Auxiliary Tree 3 | documentation_of: ../../tree/auxiliary_tree.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Auxiliary tree は,木の頂点のある部分集合と集合内の頂点間の LCA のみを含み,頂点同士の関係を保ったままもとの木を圧縮したものである. 9 | 10 | ## Operations 11 | 12 | - `AuxiliaryTree(vector> G, int root)` 13 | - 前計算をする 14 | - 時間計算量: $O(n\log n)$ 15 | - `vector> query(vector vs)` 16 | - 頂点集合 `vs` から定まる auxiliary tree の辺を返す 17 | - 時間計算量: $O(k\log n)$ 18 | 19 | ## Reference 20 | 21 | - [LCAをベースに構築するAuxiliary Treeのメモ](https://smijake3.hatenablog.com/entry/2019/09/15/200200) 22 | - verify: [https://atcoder.jp/contests/typical90/submissions/30186948](https://atcoder.jp/contests/typical90/submissions/30186948) -------------------------------------------------------------------------------- /docs/tree/cartesian_tree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cartesian Tree 3 | documentation_of: ../../tree/cartesian_tree.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Cartesian tree は,数列から定まる二分木で,以下の条件を満たすものである. 9 | - 各頂点の重みは,そのどの子の重みよりも小さい 10 | - 木の in-order traversal がもとの数列と一致する 11 | 12 | ## Operations 13 | 14 | - `vector cartesian_tree(vector a)` 15 | - 数列 $a$ から定まる Cartesian tree を返す.それぞれの頂点の親のラベルを返す.根の親は `-1` とする. 16 | - 時間計算量: $O(n)$ 17 | 18 | ## Reference 19 | 20 | - [列を最小値で分割して再帰するパターンと Cartesian tree](https://kmyk.github.io/blog/blog/2020/07/27/recursion-on-cartesian-tree/) -------------------------------------------------------------------------------- /docs/tree/centroid_decomposition.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Centroid Decomposition 3 | documentation_of: ../../tree/centroid_decomposition.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 木の重心とは,木の頂点であって,その頂点を除いてできる森の各連結成分のサイズがもとの木の半分以下になるようなものである. 9 | 10 | 木の重心による分割を再帰的に行う.木上の分割統治に用いる. 11 | 12 | ## Operations 13 | 14 | - `tuple, vector, vector> centroid_decomposition(vector> G)` 15 | - 木 $G$ の隣接リストが与えられたとき,3つ組 `(level, sz, par)` を返す. 16 | - `level`: $G$ を重心分解したときの各頂点のレベル (何回目の分割でそれが重心となるか) 17 | - `sz`: 各頂点が重心となるときにそれが含まれる部分木のサイズ 18 | - `par`: 各頂点が重心となる直前に属していた部分木の重心 19 | - 時間計算量: $O(n\log n)$ 20 | 21 | ## Reference 22 | 23 | - [ツリーの重心分解 (木の重心分解) の図解 - Qiita](https://qiita.com/drken/items/4b4c3f1824339b090202) 24 | -------------------------------------------------------------------------------- /docs/tree/permutation_tree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Permutation Tree 3 | documentation_of: ../../tree/permutation_tree.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | Permutation tree は,順列の区間のマージ過程を表す木である.$\max_{l\leq i < r} p_i - \min_{l\leq i < r} p_i = r - l$ となるような区間の数え上げなどに使える. 9 | 10 | ## Operations 11 | 12 | - `PermutationTree(vector p)` 13 | - 順列 $p$ から permutation tree を構築する. 14 | - 時間計算量: $O(n\log n)$ 15 | 16 | ## Reference 17 | 18 | - [Tutorial on Permutation Tree (析合树) - Codeforces](https://codeforces.com/blog/entry/78898) 19 | - [Permutation tree (順列木) - cplib-cpp](https://hitonanode.github.io/cplib-cpp/other_algorithms/permutation_tree.hpp.html) 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/tree/range_contour_aggregation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Range Contour Aggregation 3 | documentation_of: ../../tree/range_contour_aggregation.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | 木上の等高線集約クエリ (の変種1) (参考文献を参照) を扱う. 9 | 10 | 空間計算量: $O(n\log n)$ 11 | 12 | ## Operations 13 | 14 | - `RangeContourAggregation(vector> G)` 15 | - 木 $G$ に対する前計算を行う 16 | - 時間計算量: $O(n\log n)$ 17 | - `void update(int v, T x)` 18 | - 頂点 $v$ の値を $x$ に更新する 19 | - 時間計算量: $O((\log n)^2)$ 20 | - `T fold(int v, int d)` 21 | - $v$ からの距離が $d$ 未満の頂点の値の総和を求める 22 | - 時間計算量: $O((\log n)^2)$ 23 | 24 | ## Reference 25 | 26 | - [木上の等高線集約クエリ - suisen のブログ](https://suisen-kyopro.hatenablog.com/entry/2022/03/21/220009) -------------------------------------------------------------------------------- /docs/tree/tree_diameter.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Diameter of a Tree 3 | documentation_of: ../../tree/tree_diameter.hpp 4 | --- 5 | 6 | ## Description 7 | 8 | DFSを用いて木の直径を求める. 9 | 10 | ## Operations 11 | 12 | - `pair> tree_diameter(vector> G)` 13 | - $G$ の辺の重みをすべて1として直径の重みとそれに含まれる頂点を返す 14 | - 時間計算量: $O(n)$ 15 | - `pair> tree_diameter(vector>> G)` 16 | - $G$ の直径の重みとそれに含まれる頂点を返す 17 | - 時間計算量: $O(n)$ 18 | 19 | ## Reference 20 | 21 | - [木の直径を求めるアルゴリズム](https://algo-logic.info/tree-diameter/) -------------------------------------------------------------------------------- /dp/edit_distance.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | /** 7 | * @brief Edit Distance 8 | */ 9 | int edit_distance(const std::string& s, const std::string& t) { 10 | const int n = s.size(), m = t.size(); 11 | std::vector dp(n + 1, std::vector(m + 1)); 12 | dp[0][0] = 0; 13 | for (int i = 1; i <= n; ++i) dp[i][0] = i; 14 | for (int j = 1; j <= m; ++j) dp[0][j] = j; 15 | for (int i = 1; i <= n; ++i) { 16 | for (int j = 1; j <= m; ++j) { 17 | dp[i][j] = std::min({ 18 | dp[i - 1][j] + 1, // insert 19 | dp[i][j - 1] + 1, // delete 20 | dp[i - 1][j - 1] + (s[i - 1] != t[j - 1]) // replace 21 | }); 22 | } 23 | } 24 | return dp[n][m]; 25 | } -------------------------------------------------------------------------------- /dp/lcs.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | /** 7 | * @brief Longest Common Subsequence 8 | */ 9 | int longest_common_subsequence(const std::string& s, const std::string& t) { 10 | const int n = s.size(), m = t.size(); 11 | std::vector dp(n + 1, std::vector(m + 1)); 12 | for (int i = 0; i < n; ++i) { 13 | for (int j = 0; j < m; ++j) { 14 | if (s[i] == t[j]) { 15 | dp[i + 1][j + 1] = dp[i][j] + 1; 16 | } else { 17 | dp[i + 1][j + 1] = std::max(dp[i][j + 1], dp[i + 1][j]); 18 | } 19 | } 20 | } 21 | return dp[n][m]; 22 | } 23 | -------------------------------------------------------------------------------- /dp/monotone_minima.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | template 5 | std::vector monotone_minima(int n, int m, const F& f) { 6 | std::vector idx(n, -1); 7 | 8 | auto calc = [&](const auto& calc, int l, int r, int optl, 9 | int optr) -> void { 10 | if (l > r) return; 11 | int m = std::midpoint(l, r); 12 | auto mi = f(m, optl); 13 | idx[m] = optl; 14 | for (int i = optl + 1; i <= optr; ++i) { 15 | auto v = f(m, i); 16 | if (mi > v) { 17 | mi = v; 18 | idx[m] = i; 19 | } 20 | } 21 | calc(calc, l, m - 1, optl, idx[m]); 22 | calc(calc, m + 1, r, idx[m], optr); 23 | }; 24 | 25 | calc(calc, 0, n - 1, 0, m - 1); 26 | return idx; 27 | } -------------------------------------------------------------------------------- /geometry/bisector.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "geometry.hpp" 3 | #include "intersection.hpp" 4 | 5 | Line bisector(const Segment& s) { 6 | auto m = (s.p1 + s.p2) / T(2); 7 | return Line(m, m + Vec(-s.dir().imag(), s.dir().real())); 8 | } 9 | 10 | std::pair bisector(const Line& l, const Line& m) { 11 | // parallel 12 | if (eq(cross(l.dir(), m.dir()), 0)) { 13 | auto n = Line(l.p1, l.p1 + perp(l.dir())); 14 | auto p = intersection(n, m); 15 | auto m = (l.p1 + p) / T(2); 16 | return {Line(m, m + l.dir()), Line()}; 17 | } 18 | auto p = intersection(l, m); 19 | T ang = (std::arg(l.dir()) + std::arg(m.dir())) / T(2); 20 | auto b1 = Line(p, p + std::polar(T(1), ang)); 21 | auto b2 = Line(p, p + std::polar(T(1), ang + PI / T(2))); 22 | return {b1, b2}; 23 | } 24 | -------------------------------------------------------------------------------- /geometry/dist.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "geometry.hpp" 3 | #include "intersect.hpp" 4 | 5 | T dist(const Line& l, const Vec& p) { 6 | return std::abs(cross(p - l.p1, l.dir())) / std::abs(l.dir()); 7 | } 8 | 9 | T dist(const Segment& s, const Vec& p) { 10 | if (lt(dot(p - s.p1, s.dir()), 0)) return std::abs(p - s.p1); 11 | if (lt(dot(p - s.p2, -s.dir()), 0)) return std::abs(p - s.p2); 12 | return std::abs(cross(p - s.p1, s.dir())) / std::abs(s.dir()); 13 | } 14 | 15 | T dist(const Segment& s, const Segment& t) { 16 | if (intersect(s, t)) return T(0); 17 | return std::min( 18 | {dist(s, t.p1), dist(s, t.p2), dist(t, s.p1), dist(t, s.p2)}); 19 | } 20 | -------------------------------------------------------------------------------- /graph/topological_sort.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | std::vector topological_sort(const std::vector>& G) { 7 | const int n = G.size(); 8 | std::vector par_count(n); 9 | for (int u = 0; u < n; ++u) { 10 | for (int v : G[u]) ++par_count[v]; 11 | } 12 | std::stack st; 13 | for (int v = 0; v < n; ++v) { 14 | if (par_count[v] == 0) st.push(v); 15 | } 16 | 17 | std::vector ord; 18 | while (!st.empty()) { 19 | int u = st.top(); 20 | st.pop(); 21 | ord.push_back(u); 22 | for (int v : G[u]) { 23 | --par_count[v]; 24 | if (par_count[v] == 0) st.push(v); 25 | } 26 | } 27 | 28 | if (*std::ranges::max_element(par_count) > 0) return {}; 29 | return ord; 30 | } -------------------------------------------------------------------------------- /icpc-document/README.md: -------------------------------------------------------------------------------- 1 | # ICPC 用ドキュメント 2 | 3 | [横浜国立大学競技プログラミング部の ICPC ライブラリ](https://github.com/YNUCPC/ynu-icpc-library) の tex テンプレートを使用している. 4 | 5 | ## ファイル 6 | 7 | - `preamble.tex` 8 | - 必要なパッケージのインポートや見た目の設定 9 | - `main.tex` 10 | - セクションの定義 11 | - `{section name}.tex` 12 | - 各セクション 13 | - `file_list.py` 14 | - ドキュメントに載せるセクションとファイルのリスト 15 | - `generate.py` 16 | - リストのファイルから,各セクションのファイルを自動生成するスクリプト 17 | - `template` 18 | - `generate.py` で使うための雛形 19 | 20 | ## 作成方法 21 | 22 | 1. `file_list.py` に,ドキュメントに載せるセクションとファイルをリストする. 23 | 2. `generate.py` を実行して,tex ファイルを自動生成する 24 | 3. (ドキュメントを手動で添削する) 25 | 4. `latexmk main.tex` を実行して `main.pdf` を生成する -------------------------------------------------------------------------------- /icpc-document/antbook.tex: -------------------------------------------------------------------------------- 1 | \section{蟻本} 2 | 3 | \begin{itemize} 4 | \item ナップザック: p.52~ 5 | \item LCS: p.56 6 | \item LIS: p.63 7 | \item 分割数: p.66 8 | \item 最短路: p.94 9 | \item MST: p.99 10 | \item extgcd: p.108 11 | \item 素数: p.110 12 | \item ビット演算テク,部分集合の列挙: p.144 13 | \item 最大流テク: p.192 14 | \item マッチングと被覆: p.198 15 | \item 最小費用流テク: p.204 16 | \item シンプソン公式: p.237 17 | \item メビウス関数: p.265 18 | \item 最大長方形: p.298 19 | \item スライド最小値: p.300 20 | \item 最近点対: p.324 21 | \end{itemize} -------------------------------------------------------------------------------- /icpc-document/main.markdown.lua: -------------------------------------------------------------------------------- 1 | local ran_ok, error = pcall(function() local ran_ok, kpse = pcall(require, "kpse") if ran_ok then kpse.set_program_name("luatex") end local lfs = require("lfs") local cacheDir = "./_markdown_main" if not lfs.isdir(cacheDir) then assert(lfs.mkdir(cacheDir)) end local md = require("markdown") local convert = md.new({cacheDir = "./_markdown_main", frozenCacheFileName = "./_markdown_main/frozenCache.tex", frozenCacheCounter = 0, hybrid = true, } ) local file = assert(io.open("./main.markdown.in", "r"), [[could not open file "./main.markdown.in" for reading]]) local input = assert(file:read("*a")) assert(file:close()) print(convert(input:gsub("\r\n?", "\n") .. "\n")) end) if not ran_ok then local file = io.open("./main.markdown.err", "w") if file then file:write(error .. "\n") file:close() end print('\\markdownError{An error was encountered while executing Lua code}{For further clues, examine the file "./main.markdown.err"}') end 2 | -------------------------------------------------------------------------------- /icpc-document/main.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sotanishy/cp-library-cpp/1175ff88cf60d3ef46712d87589c47726eaa3458/icpc-document/main.pdf -------------------------------------------------------------------------------- /icpc-document/main.tex: -------------------------------------------------------------------------------- 1 | \documentclass[9pt,a4paper,landscape,twocolumn,dvipdfmx]{jsarticle} % 用紙横向き、二段組 2 | 3 | \input{preamble.tex} 4 | 5 | \begin{document} 6 | 7 | % 目次の出力 8 | \tableofcontents 9 | \clearpage 10 | 11 | % 本文 12 | % \input{template.tex} 13 | % \input{antbook.tex} 14 | % \input{convolution.tex} 15 | \input{data-structure.tex} 16 | % \input{flow.tex} 17 | % \input{geometry.tex} 18 | % \input{graph.tex} 19 | \input{math.tex} 20 | % \input{misc.tex} 21 | % \input{sat.tex} 22 | \input{string.tex} 23 | \input{tree.tex} 24 | 25 | \end{document} 26 | -------------------------------------------------------------------------------- /icpc-document/template.tex: -------------------------------------------------------------------------------- 1 | \section{初期設定} 2 | 3 | \subsection{テンプレート} 4 | 5 | \begin{lstlisting} 6 | #pragma once 7 | #include 8 | using namespace std; 9 | using ll = long long; 10 | #define rep(i,s,t) for (int i = (int)(s); i < (int)(t); ++i) 11 | #define all(x) (x).begin(), (x).end() 12 | 13 | int main() { 14 | ios_base::sync_with_stdio(false); 15 | cin.tie(nullptr); 16 | 17 | } 18 | \end{lstlisting} 19 | 20 | \subsection{コンパイルのalias} 21 | 22 | \begin{lstlisting}[language=bash] 23 | alias gxx='g++ -std=c++17 -Wall -Wextra -fsanitize=undefined -D_GLIBCXX_DEBUG' 24 | \end{lstlisting} 25 | -------------------------------------------------------------------------------- /icpc-document/template/main.tex: -------------------------------------------------------------------------------- 1 | \documentclass[9pt,a4paper,landscape,twocolumn,dvipdfmx]{jsarticle} % 用紙横向き、二段組 2 | 3 | \input{preamble.tex} 4 | 5 | \begin{document} 6 | 7 | % 目次の出力 8 | \tableofcontents 9 | \clearpage 10 | 11 | % 本文 12 | \input{template.tex} 13 | \input{antbook.tex} 14 | {%- for sec in sections %} 15 | \input{ {{-sec}}.tex} 16 | {%- endfor %} 17 | 18 | \end{document} 19 | 20 | -------------------------------------------------------------------------------- /icpc-document/template/section.tex: -------------------------------------------------------------------------------- 1 | \section{ {{-section.title-}} } 2 | 3 | {%- for file in section.files %} 4 | 5 | \subsection{ {{-file.title-}} } 6 | 7 | \begin{small} 8 | \begin{markdown} 9 | {{ file.doc }} 10 | \end{markdown} 11 | \end{small} 12 | 13 | \begin{lstlisting} 14 | {{ file.src }} 15 | \end{lstlisting} 16 | 17 | 18 | {%- endfor %} -------------------------------------------------------------------------------- /math/convert_base.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | std::vector convert_base(int n, int base) { 5 | int q = n / base, r = n % base; 6 | if (q == 0) return {r}; 7 | auto ret = convert_base(q, base); 8 | ret.push_back(r); 9 | return ret; 10 | } -------------------------------------------------------------------------------- /math/count_subset_sum.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "polynomial.cpp" 5 | 6 | template 7 | std::vector count_subset_sum(const std::vector& val, int V) { 8 | std::vector a(V + 1); 9 | for (auto x : val) { 10 | a[x] += 1; 11 | } 12 | 13 | std::vector inv(V + 1); 14 | for (int i = 1; i <= V; ++i) inv[i] = mint(1) / i; 15 | 16 | Polynomial f(V + 1); 17 | for (int k = 1; k <= V; ++k) { 18 | if (a[k] == 0) continue; 19 | for (int i = 1; k * i <= V; ++i) { 20 | f[k * i] += mint(i % 2 == 0 ? -1 : 1) * a[k] * inv[i]; 21 | } 22 | } 23 | return f.exp(); 24 | } 25 | -------------------------------------------------------------------------------- /math/lagrange_interpolation.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | template 5 | T lagrange_interpolation(const std::vector& f, long long n) { 6 | const int d = f.size() - 1; 7 | std::vector fact(d + 1, 1), fact_inv(d + 1, 1); 8 | for (int i = 1; i <= d; ++i) fact[i] = fact[i - 1] * i; 9 | fact_inv[d] = T(1) / fact[d]; 10 | for (int i = d; i > 0; --i) fact_inv[i - 1] = fact_inv[i] * i; 11 | 12 | std::vector num(d + 1, 1); 13 | T a = 1; 14 | for (int i = 0; i <= d; ++i) { 15 | num[i] *= a; 16 | a *= n - i; 17 | } 18 | a = 1; 19 | for (int i = d; i >= 0; --i) { 20 | num[i] *= a; 21 | a *= n - i; 22 | } 23 | T ans = 0; 24 | for (int i = 0; i <= d; ++i) { 25 | ans += ((i + d) & 1 ? -1 : 1) * f[i] * num[i] * fact_inv[i] * fact_inv[d - i]; 26 | } 27 | return ans; 28 | } -------------------------------------------------------------------------------- /math/montmort.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | /* 5 | * @brief Monmort Number 6 | */ 7 | template 8 | std::vector montmort_table(int n) { 9 | std::vector ret(n + 1); 10 | if (n == 1) return ret; 11 | ret[2] = 1; 12 | for (int i = 3; i <= n; ++i) { 13 | ret[i] = (ret[i - 1] + ret[i - 2]) * (i - 1); 14 | } 15 | return ret; 16 | } -------------------------------------------------------------------------------- /math/multipoint_evaluation.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "polynomial.cpp" 5 | 6 | template 7 | std::vector multipoint_evaluation(const Polynomial& p, 8 | const std::vector& x) { 9 | int m = x.size(); 10 | int n = 1; 11 | while (n < m) n <<= 1; 12 | std::vector> q(2 * n, {1}); 13 | for (int i = 0; i < m; ++i) q[n + i] = {-x[i], 1}; 14 | for (int i = n - 1; i > 0; --i) q[i] = q[2 * i] * q[2 * i + 1]; 15 | q[1] = p % q[1]; 16 | for (int i = 2; i < n + m; ++i) q[i] = q[i / 2] % q[i]; 17 | std::vector y(m); 18 | for (int i = 0; i < m; ++i) y[i] = q[n + i].empty() ? 0 : q[n + i][0]; 19 | return y; 20 | } -------------------------------------------------------------------------------- /math/number-theory/carmichael.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #include "prime.hpp" 6 | 7 | long long carmichael(long long n) { 8 | long long ret = 1; 9 | for (auto [p, e] : prime_factor(n)) { 10 | long long lambda = std::pow(p, e - 1) * (p - 1); 11 | if (p == 2 && e >= 3) lambda /= 2; 12 | ret = ret / std::gcd(ret, lambda) * lambda; 13 | } 14 | return ret; 15 | } -------------------------------------------------------------------------------- /math/number-theory/divisor.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | std::vector divisor(long long n) { 5 | std::vector ret1, ret2; 6 | for (long long i = 1; i * i <= n; ++i) { 7 | if (i * i == n) { 8 | ret1.push_back(i); 9 | } else if (n % i == 0) { 10 | ret1.push_back(i); 11 | ret2.push_back(n / i); 12 | } 13 | } 14 | ret1.insert(ret1.end(), ret2.rbegin(), ret2.rend()); 15 | return ret1; 16 | } -------------------------------------------------------------------------------- /math/number-theory/extgcd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | std::pair extgcd(long long a, long long b) { 6 | long long s = a, sx = 1, sy = 0, t = b, tx = 0, ty = 1; 7 | while (t) { 8 | long long q = s / t; 9 | std::swap(s -= t * q, t); 10 | std::swap(sx -= tx * q, tx); 11 | std::swap(sy -= ty * q, ty); 12 | } 13 | return {sx, sy}; 14 | } 15 | 16 | long long mod_inv(long long a, long long mod) { 17 | long long inv = extgcd(a, mod).first; 18 | return (inv % mod + mod) % mod; 19 | } -------------------------------------------------------------------------------- /math/number-theory/farey_sequence.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | /** 6 | * @brief Farey Sequence 7 | */ 8 | std::vector> farey_sequence(int n) { 9 | int a = 0, b = 1, c = 1, d = n; 10 | std::vector> seq; 11 | seq.push_back({a, b}); 12 | seq.push_back({c, d}); 13 | while (d != 1) { 14 | int k = (n + b) / d; 15 | int e = k * c - a; 16 | int f = k * d - b; 17 | seq.push_back({e, f}); 18 | a = c; 19 | b = d; 20 | c = e; 21 | d = f; 22 | } 23 | return seq; 24 | } -------------------------------------------------------------------------------- /math/number-theory/floor_sum.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | long long floor_sum(long long n, long long m, long long a, long long b) { 4 | long long sum = 0; 5 | if (a >= m) { 6 | sum += (a / m) * n * (n - 1) / 2; 7 | a %= m; 8 | } 9 | if (b >= m) { 10 | sum += (b / m) * n; 11 | b %= m; 12 | } 13 | long long y = (a * n + b) / m; 14 | if (y == 0) return sum; 15 | long long x = (m * y - b + a - 1) / a; 16 | sum += (n - x) * y + floor_sum(y, a, m, a * x - m * y + b); 17 | return sum; 18 | } -------------------------------------------------------------------------------- /math/number-theory/garner.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "extgcd.hpp" 5 | 6 | long long garner(const std::vector& b, std::vector m, 7 | long long mod) { 8 | m.push_back(mod); 9 | const int n = m.size(); 10 | std::vector coeffs(n, 1); 11 | std::vector consts(n, 0); 12 | for (int k = 0; k < n - 1; ++k) { 13 | long long t = (b[k] - consts[k]) * mod_inv(coeffs[k], m[k]) % m[k]; 14 | if (t < 0) t += m[k]; 15 | for (int i = k + 1; i < n; ++i) { 16 | consts[i] = (consts[i] + t * coeffs[i]) % m[i]; 17 | coeffs[i] = coeffs[i] * m[k] % m[i]; 18 | } 19 | } 20 | return consts.back(); 21 | } -------------------------------------------------------------------------------- /math/number-theory/isqrt.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /** 4 | * @brief Integer Square Root 5 | */ 6 | unsigned long long isqrt(unsigned long long n) { 7 | unsigned long long x0 = n / 2; 8 | if (x0 == 0) return n; 9 | unsigned long long x1 = (x0 + n / x0) / 2; 10 | while (x1 < x0) { 11 | x0 = x1; 12 | x1 = (x0 + n / x0) / 2; 13 | } 14 | return x0; 15 | } -------------------------------------------------------------------------------- /math/number-theory/kth_root.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | /** 6 | * @brief Integer Kth Root 7 | */ 8 | unsigned long long kth_root(unsigned long long x, int k) { 9 | using ull = unsigned long long; 10 | assert(k >= 1); 11 | if (x <= 1 || k == 1) return x; 12 | auto check = [&](ull a) { 13 | ull y = x; 14 | int e = k; 15 | while (e) { 16 | if (e & 1) { 17 | if (a == 0) return false; 18 | y /= a; 19 | } 20 | if (a > 0 && a > y / a) 21 | a = 0; 22 | else 23 | a *= a; 24 | e >>= 1; 25 | } 26 | return y > 0; 27 | }; 28 | ull res = std::pow(x, std::nextafter(1.0 / k, 0.0)); 29 | while (check(res + 1)) ++res; 30 | return res; 31 | } -------------------------------------------------------------------------------- /math/number-theory/primitive_root.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "fast_prime.hpp" 5 | 6 | long long primitive_root(long long p) { 7 | auto prime = fast_prime::prime_factor(p - 1); 8 | 9 | using mint = fast_prime::LargeModint; 10 | mint::set_mod(p); 11 | 12 | std::random_device rd; 13 | std::mt19937_64 rng(rd()); 14 | std::uniform_int_distribution rand(1, p - 1); 15 | while (true) { 16 | long long x = rand(rng); 17 | mint a = x; 18 | bool ok = true; 19 | for (auto pi : prime) { 20 | if (a.pow((p - 1) / pi) == 1) { 21 | ok = false; 22 | break; 23 | } 24 | } 25 | if (ok) return a.val(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /math/number-theory/quotients.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | /** 5 | * @brief Intervals with Equal Quotients 6 | */ 7 | template 8 | std::vector> quotient_ranges(T n) { 9 | std::vector> ret; 10 | T i = 1; 11 | while (i <= n) { 12 | T q = n / i; 13 | T j = n / q + 1; 14 | ret.emplace_back(i, j); 15 | i = j; 16 | } 17 | return ret; 18 | } 19 | -------------------------------------------------------------------------------- /math/partition_function.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "polynomial.cpp" 3 | 4 | template 5 | Polynomial partition_function_table(int n) { 6 | Polynomial den(n + 1); 7 | den[0] = 1; 8 | for (int k = 1; k * (3 * k - 1) / 2 <= n; ++k) { 9 | T b = k % 2 == 0 ? 1 : -1; 10 | den[k * (3 * k - 1) / 2] = b; 11 | if (k * (3 * k + 1) / 2 <= n) { 12 | den[k * (3 * k + 1) / 2] = b; 13 | } 14 | } 15 | return den.inv(); 16 | } -------------------------------------------------------------------------------- /math/product_of_polynomial_sequence.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "polynomial.cpp" 4 | 5 | /** 6 | * @brief Product of Polynomial Sequence 7 | * O(n (log n)^2) 8 | */ 9 | template 10 | Polynomial product_of_polynomial_sequence( 11 | const std::vector> polys) { 12 | if (polys.empty()) return {1}; 13 | auto dfs = [&](auto& dfs, int l, int r) -> Polynomial { 14 | if (l + 1 == r) return polys[l]; 15 | int m = (l + r) / 2; 16 | return dfs(dfs, l, m) * dfs(dfs, m, r); 17 | }; 18 | return dfs(dfs, 0, polys.size()); 19 | } -------------------------------------------------------------------------------- /math/set/and_or_convolution.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #include "zeta_moebius_transform.hpp" 6 | 7 | /** 8 | * @brief Bitwise AND/OR Convolution 9 | */ 10 | 11 | template 12 | std::vector and_convolution(std::vector a, std::vector b) { 13 | const int n = std::bit_ceil(std::max(a.size(), b.size())); 14 | a.resize(n); 15 | b.resize(n); 16 | superset_fzt(a); 17 | superset_fzt(b); 18 | for (int i = 0; i < n; ++i) a[i] *= b[i]; 19 | superset_fmt(a); 20 | return a; 21 | } 22 | 23 | template 24 | std::vector or_convolution(std::vector a, std::vector b) { 25 | const int n = std::bit_ceil(std::max(a.size(), b.size())); 26 | a.resize(n); 27 | b.resize(n); 28 | subset_fzt(a); 29 | subset_fzt(b); 30 | for (int i = 0; i < n; ++i) a[i] *= b[i]; 31 | subset_fmt(a); 32 | return a; 33 | } 34 | -------------------------------------------------------------------------------- /math/stirling_first.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "polynomial.cpp" 3 | 4 | template 5 | Polynomial stirling_first_table(int n) { 6 | if (n == 0) return {1}; 7 | Polynomial ret = stirling_first_table(n / 2); 8 | ret *= ret.taylor_shift(-(n / 2)); 9 | if (n % 2) ret = (ret << 1) + ret * (-(n - 1)); // ret *= (x - (n - 1)) 10 | return ret; 11 | } -------------------------------------------------------------------------------- /math/stirling_second.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../convolution/ntt.hpp" 4 | #include "combination.cpp" 5 | 6 | template 7 | std::vector stirling_second_table(int n) { 8 | T f = 1; 9 | for (int i = 1; i <= n; ++i) f *= i; 10 | f = T(1) / f; 11 | std::vector a(n + 1), b(n + 1); 12 | for (int i = n; i >= 0; --i) { 13 | a[i] = f * (i % 2 ? -1 : 1); 14 | b[i] = f * T(i).pow(n); 15 | f *= i; 16 | } 17 | auto c = convolution(a, b); 18 | return std::vector(c.begin(), c.begin() + n + 1); 19 | } 20 | 21 | template 22 | T stirling_second(int n, int k) { 23 | Combination comb(n); 24 | T res = 0; 25 | for (int i = 0; i <= k; ++i) { 26 | T tmp = comb.comb(k, i) * T(i).pow(n); 27 | if ((k - i) & 1) res -= tmp; 28 | else res += tmp; 29 | } 30 | res /= comb.fact(k); 31 | return res; 32 | } -------------------------------------------------------------------------------- /misc/enumerate_subsets.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | /** 5 | * @brief Enumerate Subsets 6 | */ 7 | std::vector enumerate_subsets(int n, int k) { 8 | if (k < 0 || n < k) return {}; 9 | if (k == 0) return {0}; 10 | std::vector ret; 11 | int comb = (1 << k) - 1; 12 | while (comb < (1 << n)) { 13 | ret.push_back(comb); 14 | int x = comb & -comb; 15 | int y = comb + x; 16 | comb = ((comb & ~y) / x >> 1) | y; 17 | } 18 | return ret; 19 | } -------------------------------------------------------------------------------- /misc/majority.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | template 6 | std::optional majority(const std::vector& v) { 7 | T m; 8 | int cnt = 0; 9 | for (auto x : v) { 10 | if (cnt == 0) { 11 | m = x; 12 | ++cnt; 13 | } else if (m == x) { 14 | ++cnt; 15 | } else { 16 | --cnt; 17 | } 18 | } 19 | cnt = 0; 20 | for (auto x : v) { 21 | if (m == x) { 22 | ++cnt; 23 | } 24 | } 25 | return cnt > (int)v.size() / 2 ? std::optional(m) : std::nullopt; 26 | } -------------------------------------------------------------------------------- /misc/memo.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sotanishy/cp-library-cpp/1175ff88cf60d3ef46712d87589c47726eaa3458/misc/memo.hpp -------------------------------------------------------------------------------- /misc/min_periodic_function.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | /** 5 | * @brief Minimize Periodic Function 6 | * @see https://twitter.com/maspy_stars/status/1502589106039123970 7 | * @see https://twitter.com/noshi91/status/1477671298998616065 8 | */ 9 | template 10 | T minimize_periodic_function(int n, F f) { 11 | int a = 0, b = n, c = 2 * n; 12 | while (c - a > 2) { 13 | int l = (a + b) / 2, r = (b + c + 1) / 2; 14 | if (f(l) < f(b)) 15 | std::tie(c, b) = std::make_pair(b, l); 16 | else if (f(b) > f(r)) 17 | std::tie(a, b) = std::make_pair(b, r); 18 | else 19 | std::tie(a, c) = std::make_pair(l, r); 20 | } 21 | return f(b); 22 | } -------------------------------------------------------------------------------- /misc/random.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class Random { 4 | public: 5 | // returns a random integer in the range [0, n) 6 | unsigned int next_int(int n) { return xorshift() % n; } 7 | 8 | // returns a random double number in the range [0, 1) 9 | double next_double() { return xorshift() * (1.0 / 0xFFFFFFFFu); } 10 | 11 | private: 12 | unsigned int x = 123456789, y = 362436069, z = 521288629, w = 88675123; 13 | 14 | unsigned int xorshift() { 15 | unsigned int t; 16 | t = x ^ (x << 11); 17 | x = y; 18 | y = z; 19 | z = w; 20 | return w = w ^ (w >> 19) ^ (t ^ (t >> 8)); 21 | } 22 | }; -------------------------------------------------------------------------------- /misc/timer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class Timer { 5 | public: 6 | void start() { start_time = std::chrono::steady_clock::now(); } 7 | 8 | long long get_time() const { 9 | auto cur_time = std::chrono::steady_clock::now(); 10 | return std::chrono::duration_cast(cur_time - 11 | start_time) 12 | .count(); 13 | } 14 | 15 | private: 16 | std::chrono::steady_clock::time_point start_time; 17 | }; -------------------------------------------------------------------------------- /sat/twosat.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../graph/scc.hpp" 5 | 6 | std::vector two_sat( 7 | int n, const std::vector>& clauses) { 8 | std::vector> G(2 * n); 9 | std::vector val(n); 10 | 11 | for (auto& [i, f, j, g] : clauses) { 12 | G[n * f + i].push_back(n * (!g) + j); 13 | G[n * g + j].push_back(n * (!f) + i); 14 | } 15 | 16 | auto comp = scc(G); 17 | for (int i = 0; i < n; ++i) { 18 | if (comp[i] == comp[n + i]) { 19 | // not satisfiable 20 | return {}; 21 | } 22 | val[i] = comp[i] > comp[n + i]; 23 | } 24 | return val; 25 | } -------------------------------------------------------------------------------- /string/lcp_array.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | template 6 | std::vector lcp_array(const std::vector& s, 7 | const std::vector& sa) { 8 | const int n = s.size(); 9 | std::vector rank(n); 10 | for (int i = 0; i < n; ++i) rank[sa[i]] = i; 11 | int h = 0; 12 | std::vector lcp(n - 1); 13 | for (int i = 0; i < n; ++i) { 14 | if (h > 0) --h; 15 | if (rank[i] == 0) continue; 16 | int j = sa[rank[i] - 1]; 17 | while (j + h < n && i + h < n && s[j + h] == s[i + h]) ++h; 18 | lcp[rank[i] - 1] = h; 19 | } 20 | return lcp; 21 | } 22 | 23 | std::vector lcp_array(const std::string& s, const std::vector& sa) { 24 | return lcp_array(std::vector(s.begin(), s.end()), sa); 25 | } -------------------------------------------------------------------------------- /string/lyndon_factorization.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | std::vector lyndon_factorization(const std::string& s) { 6 | const int n = s.size(); 7 | std::vector res; 8 | for (int i = 0; i < n;) { 9 | int j = i + 1, k = i; 10 | while (j < n && s[k] <= s[j]) { 11 | if (s[k] < s[j]) { 12 | k = i; 13 | } else { 14 | ++k; 15 | } 16 | ++j; 17 | } 18 | while (i <= k) { 19 | res.push_back(i); 20 | i += j - k; 21 | } 22 | } 23 | res.push_back(n); 24 | return res; 25 | } 26 | -------------------------------------------------------------------------------- /string/z_array.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | std::vector z_array(const std::string& s) { 6 | const int n = s.size(); 7 | std::vector z(n); 8 | z[0] = n; 9 | int l = 0, r = 0; 10 | for (int i = 1; i < n; ++i) { 11 | int k = i - l; 12 | if (i <= r && z[k] < r - i + 1) { 13 | z[i] = z[k]; 14 | } else { 15 | l = i; 16 | if (i > r) r = i; 17 | while (r < n && s[r - l] == s[r]) ++r; 18 | --r; 19 | z[i] = r - l + 1; 20 | } 21 | } 22 | return z; 23 | } -------------------------------------------------------------------------------- /test/aoj/1208.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1208" 2 | 3 | #include "../../math/number-theory/stern_brocot_tree.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | cout << fixed << setprecision(15); 13 | 14 | while (true) { 15 | int p, n; 16 | cin >> p >> n; 17 | if (p == 0 && n == 0) break; 18 | auto ans = stern_brocot_tree_search(n, [&](ll a, ll b) { 19 | return a * a < p * b * b; 20 | }); 21 | auto [u, v] = ans.first; 22 | auto [x, y] = ans.second; 23 | cout << x << "/" << y << " " << u << "/" << v << endl; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/aoj/1298.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1298" 2 | 3 | #include "../../geometry/geometry.hpp" 4 | #include "../../geometry/convex_hull.hpp" 5 | #include "../../geometry/intersect.hpp" 6 | 7 | #include 8 | using namespace std; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(nullptr); 13 | cout << fixed << setprecision(15); 14 | 15 | while (true) { 16 | int n, m; 17 | cin >> n >> m; 18 | if (n == 0 && m == 0) break; 19 | vector black(n), white(m); 20 | for (auto& p : black) cin >> p; 21 | for (auto& p : white) cin >> p; 22 | black = convex_hull(black); 23 | white = convex_hull(white); 24 | cout << (intersect(black, white) ? "NO" : "YES") << "\n"; 25 | } 26 | } -------------------------------------------------------------------------------- /test/aoj/2415.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2415" 2 | 3 | #include 4 | 5 | #include "../../dp/hu_tucker.hpp" 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(0); 12 | 13 | int N; 14 | cin >> N; 15 | vector w(N); 16 | for (auto& x : w) cin >> x; 17 | cout << hu_tucker(w) << endl; 18 | } -------------------------------------------------------------------------------- /test/aoj/ALDS1_14_B.kmp.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_14_B" 3 | 4 | #include 5 | 6 | #include "../../string/kmp.hpp" 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(0); 12 | 13 | string T; 14 | cin >> T; 15 | string P; 16 | cin >> P; 17 | auto ans = kmp(T, P, prefix_function(P)); 18 | for (int i : ans) cout << i << "\n"; 19 | } 20 | -------------------------------------------------------------------------------- /test/aoj/ALDS1_14_B.rolling_hash.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_14_B" 3 | 4 | #include 5 | 6 | #include "../../string/rolling_hash.hpp" 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(0); 12 | 13 | string T; 14 | cin >> T; 15 | string P; 16 | cin >> P; 17 | long long base = RollingHash::generate_base(); 18 | RollingHash rht(T, base); 19 | RollingHash rhp(P, base); 20 | for (int i = 0; i + P.size() <= T.size(); ++i) { 21 | if (rht.query(i, i + P.size()) == rhp.query(0, P.size())) { 22 | cout << i << "\n"; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /test/aoj/ALDS1_14_C.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_14_C" 3 | 4 | #include 5 | 6 | #include "../../string/pattern_search_2d.hpp" 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(0); 12 | 13 | int H, W; 14 | cin >> H >> W; 15 | vector txt(H); 16 | for (auto& x : txt) cin >> x; 17 | int R, C; 18 | cin >> R >> C; 19 | vector pat(R); 20 | for (auto& x : pat) cin >> x; 21 | 22 | auto ans = pattern_search_2d(txt, pat); 23 | sort(ans.begin(), ans.end()); 24 | for (auto [i, j] : ans) { 25 | cout << i << " " << j << "\n"; 26 | } 27 | } -------------------------------------------------------------------------------- /test/aoj/ALDS1_1_C.is_prime.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_1_C" 2 | 3 | #include "../../math/number-theory/prime.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int n; 13 | cin >> n; 14 | int ans = 0; 15 | for (int i = 0; i < n; i++) { 16 | int a; 17 | cin >> a; 18 | if (is_prime(a)) ans++; 19 | } 20 | cout << ans << endl; 21 | } -------------------------------------------------------------------------------- /test/aoj/CGL_1_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A" 2 | #define ERROR 0.00000001 3 | 4 | #include "../../geometry/geometry.hpp" 5 | 6 | #include 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | cout << fixed << setprecision(15); 13 | 14 | Vec p1, p2; 15 | cin >> p1 >> p2; 16 | Line l(p1, p2); 17 | int q; 18 | cin >> q; 19 | while (q--) { 20 | Vec p; 21 | cin >> p; 22 | auto q = projection(l, p); 23 | cout << q.real() << " " << q.imag() << endl; 24 | } 25 | } -------------------------------------------------------------------------------- /test/aoj/CGL_1_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B" 2 | #define ERROR 0.00000001 3 | 4 | #include "../../geometry/geometry.hpp" 5 | 6 | #include 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | cout << fixed << setprecision(15); 13 | 14 | Vec p1, p2; 15 | cin >> p1 >> p2; 16 | Line l(p1, p2); 17 | int q; 18 | cin >> q; 19 | while (q--) { 20 | Vec p; 21 | cin >> p; 22 | auto q = reflection(l, p); 23 | cout << q.real() << " " << q.imag() << endl; 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /test/aoj/CGL_2_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A" 2 | 3 | #include "../../geometry/geometry.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(nullptr); 11 | 12 | int q; 13 | cin >> q; 14 | while (q--) { 15 | Vec p0, p1, p2, p3; 16 | cin >> p0 >> p1 >> p2 >> p3; 17 | auto p = p1 - p0, q = p3 - p2; 18 | if (eq(cross(p, q), 0)) { 19 | cout << 2 << "\n"; 20 | } else if (eq(dot(p, q), 0)) { 21 | cout << 1 << "\n"; 22 | } else { 23 | cout << 0 << "\n"; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /test/aoj/CGL_2_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B" 2 | 3 | #include "../../geometry/geometry.hpp" 4 | #include "../../geometry/intersect.hpp" 5 | 6 | #include 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int q; 14 | cin >> q; 15 | while (q--) { 16 | Vec p0, p1, p2, p3; 17 | cin >> p0 >> p1 >> p2 >> p3; 18 | cout << min(1, intersect(Segment(p0, p1), Segment(p2, p3))) << "\n"; 19 | } 20 | } -------------------------------------------------------------------------------- /test/aoj/CGL_2_C.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_C" 2 | #define ERROR 0.00000001 3 | 4 | #include "../../geometry/geometry.hpp" 5 | #include "../../geometry/intersection.hpp" 6 | 7 | #include 8 | using namespace std; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(nullptr); 13 | cout << fixed << setprecision(10); 14 | 15 | int q; 16 | cin >> q; 17 | while (q--) { 18 | Vec p0, p1, p2, p3; 19 | cin >> p0 >> p1 >> p2 >> p3; 20 | auto q = intersection(Line(p0, p1), Line(p2, p3)); 21 | cout << q.real() << " " << q.imag() << "\n"; 22 | } 23 | } -------------------------------------------------------------------------------- /test/aoj/CGL_2_D.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D" 2 | #define ERROR 0.00000001 3 | 4 | #include "../../geometry/geometry.hpp" 5 | #include "../../geometry/dist.hpp" 6 | 7 | #include 8 | using namespace std; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(nullptr); 13 | cout << fixed << setprecision(10); 14 | 15 | int q; 16 | cin >> q; 17 | while (q--) { 18 | Vec p0, p1, p2, p3; 19 | cin >> p0 >> p1 >> p2 >> p3; 20 | cout << dist(Segment(p0, p1), Segment(p2, p3)) << "\n"; 21 | } 22 | } -------------------------------------------------------------------------------- /test/aoj/CGL_3_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_A" 2 | 3 | #include "../../geometry/geometry.hpp" 4 | #include "../../geometry/polygon.hpp" 5 | 6 | #include 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | cout << fixed << setprecision(1); 13 | 14 | int n; 15 | cin >> n; 16 | vector pts(n); 17 | for (auto& x : pts) cin >> x; 18 | cout << area(pts) << endl; 19 | } -------------------------------------------------------------------------------- /test/aoj/CGL_3_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_B" 2 | 3 | #include "../../geometry/geometry.hpp" 4 | #include "../../geometry/polygon.hpp" 5 | 6 | #include 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | cout << fixed << setprecision(15); 13 | 14 | int n; 15 | cin >> n; 16 | vector pts(n); 17 | for (auto& x : pts) cin >> x; 18 | cout << is_convex(pts) << endl; 19 | } -------------------------------------------------------------------------------- /test/aoj/CGL_3_C.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_C" 2 | 3 | #include "../../geometry/geometry.hpp" 4 | #include "../../geometry/intersect.hpp" 5 | 6 | #include 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | cout << fixed << setprecision(15); 13 | 14 | int n; 15 | cin >> n; 16 | vector pts(n); 17 | for (auto& x : pts) cin >> x; 18 | int q; 19 | cin >> q; 20 | while (q--) { 21 | Vec p; 22 | cin >> p; 23 | cout << intersect(pts, p) << "\n"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/aoj/CGL_4_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_A" 3 | 4 | #include 5 | 6 | #include "../../geometry/convex_hull.hpp" 7 | #include "../../geometry/geometry.hpp" 8 | using namespace std; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(nullptr); 13 | 14 | int n; 15 | cin >> n; 16 | vector points(n); 17 | for (auto& p : points) cin >> p; 18 | auto ans = convex_hull(points, false); 19 | cout << ans.size() << endl; 20 | for (auto& p : ans) cout << p.real() << " " << p.imag() << "\n"; 21 | } 22 | -------------------------------------------------------------------------------- /test/aoj/CGL_4_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_B" 2 | #define ERROR 0.000001 3 | 4 | #include "../../geometry/geometry.hpp" 5 | #include "../../geometry/convex_hull.hpp" 6 | 7 | #include 8 | using namespace std; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(nullptr); 13 | cout << fixed << setprecision(15); 14 | 15 | int n; 16 | cin >> n; 17 | vector pts(n); 18 | for (auto& x : pts) cin >> x; 19 | auto ch = convex_hull(pts); 20 | int j = 0; 21 | T ans = 0; 22 | for (int i = 0; i < n; ++i) { 23 | j = max(i, j); 24 | while (lt(abs(ch[i]-ch[j%n]), abs(ch[i]-ch[(j+1)%n]))) ++j; 25 | ans = max(ans, abs(ch[j%n] - ch[i])); 26 | } 27 | cout << ans << endl; 28 | } -------------------------------------------------------------------------------- /test/aoj/CGL_4_C.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_C" 2 | #define ERROR 0.00001 3 | 4 | #include "../../geometry/geometry.hpp" 5 | #include "../../geometry/polygon.hpp" 6 | 7 | #include 8 | using namespace std; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(nullptr); 13 | cout << fixed << setprecision(15); 14 | 15 | int n; 16 | cin >> n; 17 | vector poly(n); 18 | for (auto& x : poly) cin >> x; 19 | int q; 20 | cin >> q; 21 | while (q--) { 22 | Vec p1, p2; 23 | cin >> p1 >> p2; 24 | cout << area(convex_cut(poly, Line(p1, p2))) << "\n"; 25 | } 26 | } -------------------------------------------------------------------------------- /test/aoj/CGL_5_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_5_A" 2 | #define ERROR 0.000001 3 | 4 | #include "../../geometry/geometry.hpp" 5 | #include "../../geometry/closest_pair.hpp" 6 | 7 | #include 8 | using namespace std; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(nullptr); 13 | cout << fixed << setprecision(15); 14 | 15 | int n; 16 | cin >> n; 17 | vector pts(n); 18 | for (auto& p : pts) cin >> p; 19 | cout << get<0>(closest_pair(pts)) << endl; 20 | } 21 | -------------------------------------------------------------------------------- /test/aoj/CGL_7_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_A" 2 | 3 | #include "../../geometry/geometry.hpp" 4 | #include "../../geometry/intersect.hpp" 5 | 6 | #include 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | cout << fixed << setprecision(15); 13 | 14 | 15 | Vec c1, c2; 16 | T r1, r2; 17 | cin >> c1 >> r1 >> c2 >> r2; 18 | cout << intersect(Circle(c1, r1), Circle(c2, r2)) << endl; 19 | } -------------------------------------------------------------------------------- /test/aoj/CGL_7_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_B" 2 | #define ERROR 0.000001 3 | 4 | #include "../../geometry/geometry.hpp" 5 | #include "../../geometry/dist.hpp" 6 | #include "../../geometry/triangle.hpp" 7 | 8 | #include 9 | using namespace std; 10 | 11 | int main() { 12 | ios_base::sync_with_stdio(false); 13 | cin.tie(nullptr); 14 | cout << fixed << setprecision(15); 15 | 16 | 17 | Vec p1, p2, p3; 18 | cin >> p1 >> p2 >> p3; 19 | auto c = incenter(p1, p2, p3); 20 | cout << c.real() << " " << c.imag() << " " << dist(Segment(p1, p2), c) << endl; 21 | } -------------------------------------------------------------------------------- /test/aoj/CGL_7_C.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_C" 2 | #define ERROR 0.000001 3 | 4 | #include "../../geometry/geometry.hpp" 5 | #include "../../geometry/triangle.hpp" 6 | 7 | #include 8 | using namespace std; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(nullptr); 13 | cout << fixed << setprecision(15); 14 | 15 | 16 | Vec p1, p2, p3; 17 | cin >> p1 >> p2 >> p3; 18 | auto c = circumcenter(p1, p2, p3); 19 | cout << c.real() << " " << c.imag() << " " << abs(p1 - c) << endl; 20 | } -------------------------------------------------------------------------------- /test/aoj/CGL_7_F.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_F" 2 | #define ERROR 0.00001 3 | 4 | #include "../../geometry/geometry.hpp" 5 | #include "../../geometry/tangent.hpp" 6 | 7 | #include 8 | using namespace std; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(nullptr); 13 | cout << fixed << setprecision(15); 14 | 15 | Vec p, c; 16 | T r; 17 | cin >> p >> c >> r; 18 | auto [p1, p2] = tangent_points(Circle(c, r), p); 19 | if (p1.real() > p2.real() || (p1.real() == p2.real() && p1.imag() > p2.imag())) swap(p1, p2); 20 | cout << p1.real() << " " << p1.imag() << endl; 21 | cout << p2.real() << " " << p2.imag() << endl; 22 | } 23 | -------------------------------------------------------------------------------- /test/aoj/CGL_7_I.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_I" 2 | #define ERROR 0.000001 3 | 4 | #include "../../geometry/geometry.hpp" 5 | #include "../../geometry/intersection.hpp" 6 | 7 | #include 8 | using namespace std; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(nullptr); 13 | cout << fixed << setprecision(15); 14 | 15 | Vec c1, c2; 16 | T r1, r2; 17 | cin >> c1 >> r1 >> c2 >> r2; 18 | cout << area_intersection(Circle(c1, r1), Circle(c2, r2)) << endl; 19 | } 20 | -------------------------------------------------------------------------------- /test/aoj/DPL_3_C.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_3_C" 3 | 4 | #include 5 | 6 | #include "../../dp/largest_rectangle.hpp" 7 | using namespace std; 8 | using ll = long long; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(0); 13 | 14 | int N; 15 | cin >> N; 16 | vector h(N); 17 | for (auto& x : h) cin >> x; 18 | cout << largest_rectangle(h) << endl; 19 | } 20 | -------------------------------------------------------------------------------- /test/aoj/DSL_1_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_1_B" 2 | 3 | #include "../../data-structure/unionfind/weighted_union_find.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int n, q; 13 | cin >> n >> q; 14 | WeightedUnionFind wuf(n); 15 | for (int i = 0; i < q; i++) { 16 | int t; 17 | cin >> t; 18 | if (t == 0) { 19 | int x, y, z; 20 | cin >> x >> y >> z; 21 | wuf.unite(x, y, z); 22 | } else { 23 | int x, y; 24 | cin >> x >> y; 25 | if (wuf.same(x, y)) cout << wuf.diff(x, y) << "\n"; 26 | else cout << "?\n"; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/aoj/DSL_2_B.dynamic_segment_tree.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_B" 3 | 4 | #include 5 | 6 | #include "../../data-structure/segtree/dynamic_segment_tree.hpp" 7 | using namespace std; 8 | 9 | struct Monoid { 10 | using T = int; 11 | static T id() { return 0; } 12 | static T op(T a, T b) { return a + b; } 13 | }; 14 | 15 | int main() { 16 | ios_base::sync_with_stdio(false); 17 | cin.tie(0); 18 | 19 | int n, q; 20 | cin >> n >> q; 21 | DynamicSegmentTree st(n); 22 | for (int i = 0; i < q; ++i) { 23 | int com, x, y; 24 | cin >> com >> x >> y; 25 | if (com == 0) 26 | st.update(x - 1, st[x - 1] + y); 27 | else 28 | cout << st.fold(x - 1, y) << "\n"; 29 | } 30 | } -------------------------------------------------------------------------------- /test/aoj/DSL_2_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_B" 3 | 4 | #include 5 | 6 | #include "../../data-structure/fenwick_tree.hpp" 7 | using namespace std; 8 | 9 | struct Monoid { 10 | using T = int; 11 | static T id() { return 0; } 12 | static T op(T a, T b) { return a + b; } 13 | }; 14 | 15 | int main() { 16 | ios_base::sync_with_stdio(false); 17 | cin.tie(0); 18 | 19 | int n, q; 20 | cin >> n >> q; 21 | FenwickTree ft(n); 22 | for (int i = 0; i < q; i++) { 23 | int com, x, y; 24 | cin >> com >> x >> y; 25 | if (com == 0) 26 | ft.update(x - 1, y); 27 | else 28 | cout << (ft.prefix_fold(y) - ft.prefix_fold(x - 1)) << "\n"; 29 | } 30 | } -------------------------------------------------------------------------------- /test/aoj/DSL_2_C.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_C" 2 | 3 | #include "../../data-structure/kd_tree.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int n; 13 | cin >> n; 14 | KDTree kd_tree; 15 | for (int i = 0; i < n; i++) { 16 | int x, y; 17 | cin >> x >> y; 18 | kd_tree.add_point(i, x, y); 19 | } 20 | kd_tree.build(); 21 | int q; 22 | cin >> q; 23 | for (int i = 0; i < q; i++) { 24 | int sx, tx, sy, ty; 25 | cin >> sx >> tx >> sy >> ty; 26 | auto res = kd_tree.search(sx, tx, sy, ty); 27 | sort(res.begin(), res.end()); 28 | for (int j : res) cout << j << "\n"; 29 | cout << "\n"; 30 | } 31 | } -------------------------------------------------------------------------------- /test/aoj/DSL_2_G.range_fenwick_tree.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_G" 3 | 4 | #include 5 | 6 | #include "../../data-structure/range_fenwick_tree.hpp" 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(0); 12 | 13 | int n, q; 14 | cin >> n >> q; 15 | RangeFenwickTree ft(n + 1); 16 | for (int i = 0; i < q; i++) { 17 | int type, s, t; 18 | cin >> type >> s >> t; 19 | --s; 20 | --t; 21 | if (type == 0) { 22 | int x; 23 | cin >> x; 24 | ft.add(s, t + 1, x); 25 | } else { 26 | cout << ft.prefix_sum(t + 1) - ft.prefix_sum(s) << "\n"; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /test/aoj/DSL_3_D.slide_min.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_3_D" 2 | 3 | #include "../../data-structure/slide_min.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int N, L; 13 | cin >> N >> L; 14 | vector a(N); 15 | for (int i = 0; i < N; i++) cin >> a[i]; 16 | SlideMin sm; 17 | for (int i = 0; i < L; i++) sm.push(a[i]); 18 | for (int i = L; i < N; i++) { 19 | cout << sm.get() << " "; 20 | sm.pop(); 21 | sm.push(a[i]); 22 | } 23 | cout << sm.get() << endl; 24 | } -------------------------------------------------------------------------------- /test/aoj/DSL_3_D.sparse_table.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_3_D" 3 | 4 | #include 5 | 6 | #include "../../data-structure/sparse_table.hpp" 7 | using namespace std; 8 | 9 | struct MinMonoid { 10 | using T = int; 11 | static T id() { return (1u << 31) - 1; } 12 | static T op(T a, T b) { return min(a, b); } 13 | }; 14 | 15 | int main() { 16 | ios_base::sync_with_stdio(false); 17 | cin.tie(0); 18 | 19 | int N, L; 20 | cin >> N >> L; 21 | vector a(N); 22 | for (int i = 0; i < N; i++) cin >> a[i]; 23 | SparseTable st(a); 24 | for (int i = 0; i < N - L + 1; i++) { 25 | cout << st.fold(i, i + L); 26 | if (i < N - L) 27 | cout << " "; 28 | else 29 | cout << "\n"; 30 | } 31 | } -------------------------------------------------------------------------------- /test/aoj/GRL_1_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_A" 3 | 4 | #include 5 | 6 | #include "../../graph/shortest_path.hpp" 7 | using namespace std; 8 | 9 | const int INF = 1e9; 10 | 11 | int main() { 12 | ios_base::sync_with_stdio(false); 13 | cin.tie(0); 14 | 15 | int V, E, r; 16 | cin >> V >> E >> r; 17 | vector>> G(V); 18 | for (int i = 0; i < E; i++) { 19 | int s, t, d; 20 | cin >> s >> t >> d; 21 | G[s].push_back({t, d}); 22 | } 23 | auto dist = dijkstra(G, r); 24 | for (int i = 0; i < V; i++) { 25 | if (dist[i] < INF) 26 | cout << dist[i] << "\n"; 27 | else 28 | cout << "INF\n"; 29 | } 30 | } -------------------------------------------------------------------------------- /test/aoj/GRL_1_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_B" 3 | 4 | #include 5 | 6 | #include "../../graph/shortest_path.hpp" 7 | using namespace std; 8 | 9 | const int INF = 1e9; 10 | 11 | int main() { 12 | ios_base::sync_with_stdio(false); 13 | cin.tie(0); 14 | 15 | int V, E, r; 16 | cin >> V >> E >> r; 17 | vector> G; 18 | for (int i = 0; i < E; i++) { 19 | int s, t, d; 20 | cin >> s >> t >> d; 21 | G.push_back({s, t, d}); 22 | } 23 | auto dist = bellman_ford(G, V, r); 24 | if (dist.size() == 0) 25 | cout << "NEGATIVE CYCLE\n"; 26 | else { 27 | for (int i = 0; i < V; i++) { 28 | if (dist[i] < INF) 29 | cout << dist[i] << "\n"; 30 | else 31 | cout << "INF\n"; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /test/aoj/GRL_2_A.boruvka.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_2_A" 3 | 4 | #include 5 | 6 | #include "../../graph/mst.hpp" 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(0); 12 | 13 | int V, E; 14 | cin >> V >> E; 15 | vector> G; 16 | for (int i = 0; i < E; i++) { 17 | int s, t, w; 18 | cin >> s >> t >> w; 19 | G.emplace_back(s, t, w); 20 | } 21 | cout << boruvka(G, V).first << endl; 22 | } -------------------------------------------------------------------------------- /test/aoj/GRL_2_A.kruskal.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_2_A" 3 | 4 | #include 5 | 6 | #include "../../graph/mst.hpp" 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(0); 12 | 13 | int V, E; 14 | cin >> V >> E; 15 | vector> edges; 16 | for (int i = 0; i < E; i++) { 17 | int s, t, w; 18 | cin >> s >> t >> w; 19 | edges.emplace_back(s, t, w); 20 | } 21 | cout << kruskal(edges, V).first << endl; 22 | } -------------------------------------------------------------------------------- /test/aoj/GRL_2_A.prim.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_2_A" 3 | 4 | #include 5 | 6 | #include "../../graph/mst.hpp" 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(0); 12 | 13 | int V, E; 14 | cin >> V >> E; 15 | vector>> G(V); 16 | for (int i = 0; i < E; i++) { 17 | int s, t, w; 18 | cin >> s >> t >> w; 19 | G[s].push_back({t, w}); 20 | G[t].push_back({s, w}); 21 | } 22 | cout << prim(G).first << endl; 23 | } -------------------------------------------------------------------------------- /test/aoj/GRL_3_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_3_A" 2 | 3 | #include "../../graph/lowlink.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int V, E; 13 | cin >> V >> E; 14 | vector> G(V); 15 | for (int i = 0; i < E; ++i) { 16 | int s, t; 17 | cin >> s >> t; 18 | G[s].push_back(t); 19 | G[t].push_back(s); 20 | } 21 | Lowlink lowlink(G); 22 | auto pts = lowlink.articulation; 23 | sort(pts.begin(), pts.end()); 24 | for (int v : pts) cout << v << "\n"; 25 | } -------------------------------------------------------------------------------- /test/aoj/GRL_3_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_3_B" 2 | 3 | #include "../../graph/lowlink.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int V, E; 13 | cin >> V >> E; 14 | vector> G(V); 15 | for (int i = 0; i < E; ++i) { 16 | int s, t; 17 | cin >> s >> t; 18 | G[s].push_back(t); 19 | G[t].push_back(s); 20 | } 21 | Lowlink lowlink(G); 22 | auto bridges = lowlink.bridge; 23 | sort(bridges.begin(), bridges.end()); 24 | for (auto& p : bridges) { 25 | cout << p.first << " " << p.second << "\n"; 26 | } 27 | } -------------------------------------------------------------------------------- /test/aoj/GRL_6_A.dinic.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_A" 3 | 4 | #include 5 | 6 | #include "../../flow/dinic.hpp" 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(0); 12 | 13 | int V, E; 14 | cin >> V >> E; 15 | Dinic flow(V); 16 | for (int i = 0; i < E; i++) { 17 | int u, v, c; 18 | cin >> u >> v >> c; 19 | flow.add_edge(u, v, c); 20 | } 21 | cout << flow.max_flow(0, V - 1) << endl; 22 | } -------------------------------------------------------------------------------- /test/aoj/GRL_6_A.ford_fulkerson.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_A" 3 | 4 | #include 5 | 6 | #include "../../flow/ford_fulkerson.hpp" 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(0); 12 | 13 | int V, E; 14 | cin >> V >> E; 15 | FordFulkerson flow(V); 16 | for (int i = 0; i < E; i++) { 17 | int u, v, c; 18 | cin >> u >> v >> c; 19 | flow.add_edge(u, v, c); 20 | } 21 | cout << flow.max_flow(0, V - 1) << endl; 22 | } -------------------------------------------------------------------------------- /test/aoj/GRL_6_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_B" 3 | 4 | #include 5 | 6 | #include "../../flow/min_cost_flow.hpp" 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(0); 12 | 13 | int V, E, F; 14 | cin >> V >> E >> F; 15 | MinCostFlow mcf(V); 16 | for (int i = 0; i < E; i++) { 17 | int u, v, c, d; 18 | cin >> u >> v >> c >> d; 19 | mcf.add_edge(u, v, c, d); 20 | } 21 | cout << mcf.min_cost_flow(0, V - 1, F) << endl; 22 | } -------------------------------------------------------------------------------- /test/aoj/GRL_7_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_7_A" 2 | 3 | #include "../../graph/bipartite_matching.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int X, Y, E; 13 | cin >> X >> Y >> E; 14 | BipartiteMatchingFF bm(X + Y); 15 | for (int i = 0; i < E; i++) { 16 | int x, y; 17 | cin >> x >> y; 18 | bm.add_edge(x, X + y); 19 | } 20 | cout << bm.max_matching().size() << endl; 21 | } -------------------------------------------------------------------------------- /test/aoj/NTL_1_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_1_A" 2 | 3 | #include "../../math/number-theory/prime.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int n; 13 | cin >> n; 14 | cout << n << ":"; 15 | auto prime = prime_factor(n); 16 | for (auto& p : prime) { 17 | for (int i = 0; i < p.second; i++) cout << " " << p.first; 18 | } 19 | cout << endl; 20 | } -------------------------------------------------------------------------------- /test/aoj/NTL_1_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_1_B" 2 | 3 | #include "../../math/number-theory/mod_arithmetic.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int m, n; 13 | cin >> m >> n; 14 | cout << mod_pow(m, n, 1e9 + 7) << endl; 15 | } -------------------------------------------------------------------------------- /test/aoj/NTL_1_D.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_1_D" 2 | 3 | #include "../../math/number-theory/euler_totient.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int n; 13 | cin >> n; 14 | cout << euler_totient(n) << endl; 15 | } -------------------------------------------------------------------------------- /test/yosupo/area_of_union_of_rectangles.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/area_of_union_of_rectangles" 2 | 3 | #include 4 | 5 | #include "../../misc/rectangle_union.hpp" 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int N; 14 | cin >> N; 15 | vector> rects(N); 16 | for (int i = 0; i < N; ++i) { 17 | int l, d, r, u; 18 | cin >> l >> d >> r >> u; 19 | rects[i] = {l, d, r, u}; 20 | } 21 | cout << area_of_union_of_rectangles(rects) << endl; 22 | } -------------------------------------------------------------------------------- /test/yosupo/assignment.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/assignment" 2 | 3 | #include "../../graph/assignment.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(nullptr); 13 | 14 | int N; 15 | cin >> N; 16 | vector> a(N, vector(N)); 17 | for (auto& row : a) for (auto& x : row) cin >> x, x *= -1; 18 | auto perm = assignment(a); 19 | ll X = 0; 20 | for (int i = 0; i < N; ++i) X += a[i][perm[i]]; 21 | cout << -X << endl; 22 | for (int i = 0; i < N; ++i) cout << perm[i] << (i < N-1 ? " " : "\n"); 23 | } 24 | -------------------------------------------------------------------------------- /test/yosupo/biconnected_components.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/biconnected_components" 2 | 3 | #include "../../graph/biconnected_components.hpp" 4 | 5 | #include 6 | 7 | #include "../../graph/lowlink.hpp" 8 | using namespace std; 9 | using ll = long long; 10 | 11 | int main() { 12 | ios_base::sync_with_stdio(false); 13 | cin.tie(nullptr); 14 | 15 | int N, M; 16 | cin >> N >> M; 17 | vector> G(N); 18 | for (int i = 0; i < M; ++i) { 19 | int a, b; 20 | cin >> a >> b; 21 | G[a].push_back(b); 22 | G[b].push_back(a); 23 | } 24 | Lowlink low(G); 25 | auto blocks = biconnected_components(G, low); 26 | cout << blocks.size() << endl; 27 | for (auto& block : blocks) { 28 | cout << block.size(); 29 | for (int i : block) cout << " " << i; 30 | cout << "\n"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/yosupo/binomial_coefficient_prime_mod.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/binomial_coefficient_prime_mod" 2 | 3 | #include 4 | 5 | #include "../../math/arbitrary_modint.hpp" 6 | #include "../../math/combination.cpp" 7 | using namespace std; 8 | using ll = long long; 9 | 10 | using mint = ArbitraryModint; 11 | 12 | int main() { 13 | ios_base::sync_with_stdio(false); 14 | cin.tie(nullptr); 15 | 16 | int T, m; 17 | cin >> T >> m; 18 | mint::set_mod(m); 19 | Combination comb(min(m, (int)1e7) - 1); 20 | 21 | while (T--) { 22 | int n, k; 23 | cin >> n >> k; 24 | cout << comb.comb(n, k) << "\n"; 25 | } 26 | } -------------------------------------------------------------------------------- /test/yosupo/bipartite_edge_coloring.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/bipartite_edge_coloring" 2 | 3 | #include "../../graph/bipartite_edge_coloring.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int L, R, M; 13 | cin >> L >> R >> M; 14 | vector> edges(M); 15 | map, int> idx; 16 | for (int i = 0; i < M; ++i) { 17 | pair p; 18 | cin >> p.first >> p.second; 19 | idx[p] = i; 20 | edges[i] = p; 21 | } 22 | auto ans = bipartite_edge_coloring(edges, L, R); 23 | cout << *max_element(ans.begin(), ans.end()) + 1 << "\n"; 24 | for (int i = 0; i < M; ++i) cout << ans[i] << "\n"; 25 | } -------------------------------------------------------------------------------- /test/yosupo/bipartitematching.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/bipartitematching" 2 | 3 | #include "../../graph/bipartite_matching.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int L, R, M; 13 | cin >> L >> R >> M; 14 | BipartiteMatching bm(L, R); 15 | for (int i = 0; i < M; ++i) { 16 | int a, b; 17 | cin >> a >> b; 18 | bm.add_edge(a, b); 19 | } 20 | auto ans = bm.max_matching(); 21 | cout << ans.size() << "\n"; 22 | for (auto [c, d] : ans) cout << c << " " << d << "\n"; 23 | } -------------------------------------------------------------------------------- /test/yosupo/bitwise_and_convolution.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/bitwise_and_convolution" 2 | 3 | #include 4 | 5 | #include "../../math/modint.hpp" 6 | #include "../../math/set/and_or_convolution.hpp" 7 | using namespace std; 8 | using ll = long long; 9 | 10 | using mint = Modint<998244353>; 11 | 12 | int main() { 13 | int N; 14 | cin >> N; 15 | vector a(1 << N), b(1 << N); 16 | for (auto& x : a) cin >> x; 17 | for (auto& x : b) cin >> x; 18 | auto c = and_convolution(a, b); 19 | for (int i = 0; i < (1 << N); ++i) 20 | cout << c[i] << (i < (1 << N) - 1 ? " " : "\n"); 21 | } 22 | -------------------------------------------------------------------------------- /test/yosupo/bitwise_xor_convolution.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/bitwise_xor_convolution" 2 | 3 | #include 4 | 5 | #include "../../math/modint.hpp" 6 | #include "../../convolution/xor_convolution.hpp" 7 | using namespace std; 8 | using ll = long long; 9 | 10 | using mint = Modint<998244353>; 11 | 12 | int main() { 13 | int N; 14 | cin >> N; 15 | vector a(1 << N), b(1 << N); 16 | for (auto& x : a) cin >> x; 17 | for (auto& x : b) cin >> x; 18 | auto c = xor_convolution(a, b); 19 | for (int i = 0; i < (1 << N); ++i) 20 | cout << c[i] << (i < (1 << N) - 1 ? " " : "\n"); 21 | } 22 | -------------------------------------------------------------------------------- /test/yosupo/cartesian_tree.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/cartesian_tree" 2 | 3 | #include "../../tree/cartesian_tree.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int N; 14 | cin >> N; 15 | vector a(N); 16 | for (auto& x : a) cin >> x; 17 | auto p = cartesian_tree(a); 18 | for (int i = 0; i < N; ++i) 19 | cout << (p[i] == -1 ? i : p[i]) << (i < N - 1 ? " " : "\n"); 20 | } 21 | -------------------------------------------------------------------------------- /test/yosupo/characteristic_polynomial.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/characteristic_polynomial" 2 | 3 | #include "../../math/linalg/characteristic_polynomial.hpp" 4 | 5 | #include 6 | 7 | #include "../../math/linalg/matrix.hpp" 8 | #include "../../math/modint.hpp" 9 | using namespace std; 10 | 11 | using mint = Modint<998244353>; 12 | 13 | int main() { 14 | ios_base::sync_with_stdio(false); 15 | cin.tie(nullptr); 16 | 17 | int N; 18 | cin >> N; 19 | Matrix a(N); 20 | for (int i = 0; i < N; ++i) { 21 | for (int j = 0; j < N; ++j) cin >> a[i][j]; 22 | } 23 | auto p = characteristic_polynomial(a); 24 | for (int i = 0; i <= N; ++i) { 25 | cout << (i >= (int)p.size() ? 0 : p[i]) << (i < N ? " " : "\n"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/yosupo/chromatic_number.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/chromatic_number" 2 | 3 | #include "../../graph/chromatic_number.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int N, M; 14 | cin >> N >> M; 15 | vector> G(N, vector(N)); 16 | for (int i = 0; i < M; ++i) { 17 | int u, v; 18 | cin >> u >> v; 19 | G[u][v] = G[v][u] = true; 20 | } 21 | cout << chromatic_number(G) << endl; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /test/yosupo/closest_pair.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/closest_pair" 2 | 3 | #include "../../geometry/closest_pair.hpp" 4 | 5 | #include 6 | 7 | #include "../../geometry/geometry.hpp" 8 | using namespace std; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(0); 13 | 14 | int T; 15 | cin >> T; 16 | while (T--) { 17 | int N; 18 | cin >> N; 19 | vector pts(N); 20 | for (auto& p : pts) cin >> p; 21 | auto [d, i, j] = closest_pair(pts); 22 | cout << i << " " << j << "\n"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/yosupo/convolution_mod.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod" 2 | 3 | #include "../../math/modint.hpp" 4 | #include "../../convolution/ntt.hpp" 5 | 6 | #include 7 | using namespace std; 8 | using ll = long long; 9 | 10 | using mint = Modint<998244353>; 11 | 12 | int main() { 13 | int N, M; 14 | cin >> N >> M; 15 | vector a(N), b(M); 16 | for (int i = 0; i < N; i++) cin >> a[i]; 17 | for (int i = 0; i < M; i++) cin >> b[i]; 18 | auto c = convolution(a, b); 19 | for (int i = 0; i < N + M - 1; i++) cout << c[i] << (i < N + M - 2 ? " " : "\n"); 20 | } 21 | -------------------------------------------------------------------------------- /test/yosupo/convolution_mod_1000000007.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod_1000000007" 2 | 3 | #include "../../convolution/arbitrary_mod_convolution.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int N, M; 14 | cin >> N >> M; 15 | vector a(N), b(M); 16 | for (auto& x : a) cin >> x; 17 | for (auto& x : b) cin >> x; 18 | auto c = convolution(a, b, 1e9+7); 19 | for (int i = 0; i < (int) c.size(); ++i) cout << c[i] << (i < (int)c.size()-1 ? " " : "\n"); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /test/yosupo/counting_primes.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/counting_primes" 2 | 3 | #include "../../math/number-theory/prime_count.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | long long N; 14 | cin >> N; 15 | cout << prime_count(N) << endl; 16 | } -------------------------------------------------------------------------------- /test/yosupo/directedmst.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/directedmst" 2 | 3 | #include 4 | 5 | #include "../../graph/minimum_spanning_arborescence.hpp" 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int N, M, S; 14 | cin >> N >> M >> S; 15 | vector> G(M); 16 | for (int i = 0; i < M; ++i) { 17 | int s, t, w; 18 | cin >> s >> t >> w; 19 | G[i] = {s, t, w}; 20 | } 21 | auto ans = minimum_spanning_arborescence(G, N, S); 22 | cout << ans.first << endl; 23 | for (int i = 0; i < N; ++i) 24 | cout << ans.second[i] << (i < N - 1 ? " " : "\n"); 25 | } -------------------------------------------------------------------------------- /test/yosupo/discrete_logarithm_mod.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/discrete_logarithm_mod" 2 | 3 | #include "../../math/number-theory/mod_arithmetic.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(nullptr); 11 | 12 | int T; 13 | cin >> T; 14 | for (int i = 0; i < T; ++i) { 15 | int X, Y, M; 16 | cin >> X >> Y >> M; 17 | cout << mod_log(X, Y, M) << "\n"; 18 | } 19 | } -------------------------------------------------------------------------------- /test/yosupo/dominatortree.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/dominatortree" 2 | 3 | #include "../../graph/dominator_tree.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int N, M, S; 14 | cin >> N >> M >> S; 15 | vector> G(N); 16 | for (int i = 0; i < M; ++i) { 17 | int a, b; 18 | cin >> a >> b; 19 | G[a].push_back(b); 20 | } 21 | auto dom = dominator_tree(G, S); 22 | for (int i = 0; i < N; ++i) cout << dom[i] << (i < N-1 ? " " : "\n"); 23 | } -------------------------------------------------------------------------------- /test/yosupo/double_ended_priority_queue.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/double_ended_priority_queue" 2 | 3 | #include "../../data-structure/min_max_heap.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int N, Q; 13 | cin >> N >> Q; 14 | vector S(N); 15 | for (auto& x : S) cin >> x; 16 | MinMaxHeap heap(S); 17 | for (int i = 0; i < Q; i++) { 18 | int t; 19 | cin >> t; 20 | if (t == 0) { 21 | int x; 22 | cin >> x; 23 | heap.insert(x); 24 | } else if (t == 1) { 25 | cout << heap.min_element() << "\n"; 26 | heap.erase_min(); 27 | } else { 28 | cout << heap.max_element() << "\n"; 29 | heap.erase_max(); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /test/yosupo/enumerate_cliques.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/enumerate_cliques" 2 | 3 | #include "../../math/modint.hpp" 4 | #include "../../graph/enumerate_cliques.hpp" 5 | 6 | #include 7 | using namespace std; 8 | 9 | using mint = Modint<998244353>; 10 | 11 | int main() { 12 | ios_base::sync_with_stdio(false); 13 | cin.tie(0); 14 | 15 | int N, M; 16 | cin >> N >> M; 17 | vector x(N); 18 | for (auto& y : x) cin >> y; 19 | vector> G(N, vector(N)); 20 | for (int i = 0; i < M; ++i) { 21 | int u, v; 22 | cin >> u >> v; 23 | G[u][v] = G[v][u] = true; 24 | } 25 | mint ans = 0; 26 | for (auto& clique : enumerate_cliques(G)) { 27 | mint res = 1; 28 | for (int i : clique) { 29 | res *= x[i]; 30 | } 31 | ans += res; 32 | } 33 | cout << ans << endl; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /test/yosupo/enumerate_palindromes.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/enumerate_palindromes" 2 | 3 | #include 4 | 5 | #include "../../string/manacher.hpp" 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | string S; 14 | cin >> S; 15 | auto ans = manacher(S); 16 | for (int i = 0; i < ans.size(); ++i) { 17 | if (i % 2 == 0) 18 | cout << 2 * ans[i] - 1; 19 | else 20 | cout << 2 * ans[i]; 21 | if (i < ans.size() - 1) 22 | cout << " "; 23 | else 24 | cout << endl; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/yosupo/enumerate_primes.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/enumerate_primes" 2 | 3 | #include 4 | 5 | #include "../../math/number-theory/prime.hpp" 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int N, A, B; 14 | cin >> N >> A >> B; 15 | auto is_prime = prime_table(N); 16 | vector primes; 17 | for (int i = 2; i <= N; ++i) { 18 | if (is_prime[i]) primes.push_back(i); 19 | } 20 | vector ans; 21 | for (int i = B; i < (int)primes.size(); i += A) { 22 | ans.push_back(primes[i]); 23 | } 24 | int X = ans.size(); 25 | cout << primes.size() << " " << X << endl; 26 | for (int i = 0; i < X; ++i) cout << ans[i] << (i < X - 1 ? " " : "\n"); 27 | } -------------------------------------------------------------------------------- /test/yosupo/enumerate_quotients.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/enumerate_quotients" 2 | 3 | #include 4 | 5 | #include "../../math/number-theory/quotients.hpp" 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | long long N; 13 | cin >> N; 14 | auto qr = quotient_ranges(N); 15 | vector ans; 16 | for (auto [l, r] : qr) ans.push_back(N / l); 17 | reverse(ans.begin(), ans.end()); 18 | int k = ans.size(); 19 | cout << k << endl; 20 | for (int i = 0; i < k; ++i) { 21 | cout << ans[i] << (i < k - 1 ? " " : "\n"); 22 | } 23 | } -------------------------------------------------------------------------------- /test/yosupo/exp_of_formal_power_series.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/exp_of_formal_power_series" 2 | 3 | #include "../../math/modint.hpp" 4 | #include "../../math/polynomial.cpp" 5 | 6 | #include 7 | using namespace std; 8 | 9 | 10 | using mint = Modint<998244353>; 11 | 12 | int main() { 13 | ios_base::sync_with_stdio(false); 14 | cin.tie(nullptr); 15 | 16 | int N; 17 | cin >> N; 18 | Polynomial f(N); 19 | for (int i = 0; i < N; ++i) cin >> f[i]; 20 | auto g = f.exp(); 21 | for (int i = 0; i < N; ++i) cout << g[i] << (i < N - 1 ? " " : "\n"); 22 | } 23 | -------------------------------------------------------------------------------- /test/yosupo/exp_of_set_power_series.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/exp_of_set_power_series" 2 | 3 | #include 4 | 5 | #include "../../math/modint.hpp" 6 | #include "../../math/set/set_power_series.hpp" 7 | using namespace std; 8 | using ll = long long; 9 | 10 | using mint = Modint<998244353>; 11 | 12 | int main() { 13 | int N; 14 | cin >> N; 15 | SetPowerSeries b(1 << N); 16 | for (int i = 0; i < 1 << N; ++i) cin >> b[i]; 17 | auto c = b.exp(); 18 | for (int i = 0; i < 1 << N; ++i) 19 | cout << c[i] << (i < (1 << N) - 1 ? " " : "\n"); 20 | } 21 | -------------------------------------------------------------------------------- /test/yosupo/factorial.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/factorial" 2 | 3 | #include "../../math/factorial.hpp" 4 | 5 | #include 6 | 7 | #include "../../math/modint.hpp" 8 | using namespace std; 9 | using ll = long long; 10 | 11 | using mint = Modint<998244353>; 12 | 13 | int main() { 14 | ios_base::sync_with_stdio(false); 15 | cin.tie(nullptr); 16 | 17 | int T; 18 | cin >> T; 19 | Factorial fact; 20 | while (T--) { 21 | int N; 22 | cin >> N; 23 | cout << fact.query(N) << "\n"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/yosupo/factorize.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/factorize" 2 | 3 | #include "../../math/number-theory/fast_prime.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int Q; 14 | cin >> Q; 15 | while (Q--) { 16 | ll a; 17 | cin >> a; 18 | auto ans = fast_prime::prime_factor(a); 19 | sort(ans.begin(), ans.end()); 20 | cout << ans.size(); 21 | for (ll x : ans) cout << " " << x; 22 | cout << endl; 23 | } 24 | } -------------------------------------------------------------------------------- /test/yosupo/find_linear_recurrence.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/find_linear_recurrence" 2 | 3 | #include "../../math/modint.hpp" 4 | #include "../../math/berlekamp_massey.cpp" 5 | 6 | 7 | #include 8 | using namespace std; 9 | 10 | using mint = Modint<998244353>; 11 | 12 | int main() { 13 | ios_base::sync_with_stdio(false); 14 | cin.tie(nullptr); 15 | 16 | int N; 17 | cin >> N; 18 | vector a(N); 19 | for (auto& x : a) cin >> x; 20 | auto ans = berlekamp_massey(a); 21 | cout << ans.size() << endl; 22 | for (int i = 0; i < ans.size(); ++i) { 23 | cout << ans[i]; 24 | if (i < (int) ans.size() - 1) cout << " "; 25 | } 26 | cout << endl; 27 | } -------------------------------------------------------------------------------- /test/yosupo/furthest_pair.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/furthest_pair" 2 | 3 | #include "../../geometry/furthest_pair.hpp" 4 | 5 | #include 6 | 7 | #include "../../geometry/geometry.hpp" 8 | using namespace std; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(0); 13 | cout << fixed << setprecision(15); 14 | 15 | int T; 16 | cin >> T; 17 | while (T--) { 18 | int N; 19 | cin >> N; 20 | vector pts(N); 21 | for (auto& p : pts) cin >> p; 22 | auto [d, i, j] = furthest_pair(pts); 23 | cout << i << " " << j << "\n"; 24 | } 25 | } -------------------------------------------------------------------------------- /test/yosupo/gcd_convolution.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/gcd_convolution" 2 | 3 | #include "../../math/modint.hpp" 4 | #include "../../convolution/gcd_lcm_convolution.hpp" 5 | 6 | 7 | #include 8 | using namespace std; 9 | using ll = long long; 10 | 11 | using mint = Modint<998244353>; 12 | 13 | int main() { 14 | int N; 15 | cin >> N; 16 | vector a(N+1), b(N+1); 17 | for (int i = 1; i <= N; ++i) cin >> a[i]; 18 | for (int i = 1; i <= N; ++i) cin >> b[i]; 19 | auto c = gcd_convolution(a, b); 20 | for (int i = 1; i <= N; ++i) cout << c[i] << (i < N ? " " : "\n"); 21 | } 22 | -------------------------------------------------------------------------------- /test/yosupo/gcd_of_gaussian_integers.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/gcd_of_gaussian_integers" 2 | 3 | #include 4 | 5 | #include "../../math/gaussian_integer.hpp" 6 | using namespace std; 7 | 8 | using G = GaussianInteger; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(0); 13 | 14 | int T; 15 | cin >> T; 16 | while (T--) { 17 | long long a1, b1, a2, b2; 18 | cin >> a1 >> b1 >> a2 >> b2; 19 | G x(a1, b1), y(a2, b2); 20 | auto g = G::gcd(x, y); 21 | cout << g.x << " " << g.y << "\n"; 22 | } 23 | } -------------------------------------------------------------------------------- /test/yosupo/general_matching.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/general_matching" 2 | 3 | #include "../../graph/general_matching.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int N, M; 14 | cin >> N >> M; 15 | GeneralMatching gm(N); 16 | for (int i = 0; i < M; ++i) { 17 | int u, v; 18 | cin >> u >> v; 19 | gm.add_edge(u, v); 20 | } 21 | auto ans = gm.max_matching(); 22 | cout << ans.size() << "\n"; 23 | for (auto [a, b] : ans) { 24 | cout << a << " " << b << "\n"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/yosupo/hafnian_of_matrix.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/hafnian_of_matrix" 2 | 3 | #include 4 | 5 | #include "../../math/linalg/hafnian.hpp" 6 | #include "../../math/modint.hpp" 7 | using namespace std; 8 | 9 | using mint = Modint<998244353>; 10 | 11 | int main() { 12 | ios_base::sync_with_stdio(false); 13 | cin.tie(nullptr); 14 | 15 | int N; 16 | cin >> N; 17 | vector a(N, vector(N)); 18 | for (int i = 0; i < N; ++i) { 19 | for (int j = 0; j < N; ++j) cin >> a[i][j]; 20 | } 21 | cout << hafnian(a) << endl; 22 | } 23 | -------------------------------------------------------------------------------- /test/yosupo/inv_of_formal_power_series.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/inv_of_formal_power_series" 2 | 3 | #include "../../math/modint.hpp" 4 | #include "../../math/polynomial.cpp" 5 | 6 | #include 7 | using namespace std; 8 | 9 | using mint = Modint<998244353>; 10 | 11 | int main() { 12 | ios_base::sync_with_stdio(false); 13 | cin.tie(nullptr); 14 | 15 | int N; 16 | cin >> N; 17 | Polynomial f(N); 18 | for (int i = 0; i < N; ++i) cin >> f[i]; 19 | auto g = f.inv(N); 20 | for (int i = 0; i < N; ++i) cout << g[i] << (i < N - 1 ? " " : "\n"); 21 | } 22 | -------------------------------------------------------------------------------- /test/yosupo/inverse_matrix.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/inverse_matrix" 2 | 3 | #include 4 | 5 | #include "../../math/linalg/matrix.hpp" 6 | #include "../../math/modint.hpp" 7 | using namespace std; 8 | 9 | using mint = Modint<998244353>; 10 | 11 | int main() { 12 | ios_base::sync_with_stdio(false); 13 | cin.tie(nullptr); 14 | 15 | int N; 16 | cin >> N; 17 | Matrix A(N); 18 | for (int i = 0; i < N; ++i) { 19 | for (int j = 0; j < N; ++j) cin >> A[i][j]; 20 | } 21 | if (A.det() == 0) { 22 | cout << -1 << endl; 23 | return 0; 24 | } 25 | auto B = A.inv(); 26 | for (int i = 0; i < N; ++i) { 27 | for (int j = 0; j < N; ++j) cout << B[i][j] << (j < N - 1 ? " " : "\n"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/yosupo/jump_on_tree.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/jump_on_tree" 2 | 3 | #include "../../tree/lca.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int N, Q; 14 | cin >> N >> Q; 15 | vector> G(N); 16 | for (int i = 1; i < N; ++i) { 17 | int a, b; 18 | cin >> a >> b; 19 | G[a].push_back(b); 20 | G[b].push_back(a); 21 | } 22 | LCA lca(G, 0); 23 | for (int q = 0; q < Q; ++q) { 24 | int s, t, i; 25 | cin >> s >> t >> i; 26 | cout << lca.jump(s, t, i) << "\n"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test/yosupo/kth_root_integer.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/kth_root_integer" 2 | 3 | #include "../../math/number-theory/kth_root.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int T; 13 | cin >> T; 14 | while (T--) { 15 | unsigned long long A; 16 | int K; 17 | cin >> A >> K; 18 | cout << kth_root(A, K) << "\n"; 19 | } 20 | } -------------------------------------------------------------------------------- /test/yosupo/kth_term_of_linearly_recurrent_sequence.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/kth_term_of_linearly_recurrent_sequence" 2 | 3 | #include "../../math/modint.hpp" 4 | #include "../../math/bostan_mori.hpp" 5 | 6 | #include 7 | using namespace std; 8 | 9 | using mint = Modint<998244353>; 10 | 11 | int main() { 12 | ios_base::sync_with_stdio(false); 13 | cin.tie(nullptr); 14 | 15 | int d; 16 | long long k; 17 | cin >> d >> k; 18 | vector a(d), c(d); 19 | for (auto& x : a) cin >> x; 20 | for (auto& x : c) cin >> x; 21 | cout << bostan_mori_recurrence(a, c, k) << endl; 22 | } 23 | -------------------------------------------------------------------------------- /test/yosupo/lca.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/lca" 2 | 3 | #include "../../tree/lca.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int N, Q; 14 | cin >> N >> Q; 15 | vector> G(N); 16 | for (int i = 1; i < N; ++i) { 17 | int p; 18 | cin >> p; 19 | G[p].push_back(i); 20 | } 21 | LCA lca(G, 0); 22 | for (int i = 0; i < Q; ++i) { 23 | int u, v; 24 | cin >> u >> v; 25 | cout << lca.query(u, v) << "\n"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/yosupo/lcm_convolution.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/lcm_convolution" 2 | 3 | #include "../../math/modint.hpp" 4 | #include "../../convolution/gcd_lcm_convolution.hpp" 5 | 6 | #include 7 | using namespace std; 8 | using ll = long long; 9 | 10 | using mint = Modint<998244353>; 11 | 12 | int main() { 13 | int N; 14 | cin >> N; 15 | vector a(N+1), b(N+1); 16 | for (int i = 1; i <= N; ++i) cin >> a[i]; 17 | for (int i = 1; i <= N; ++i) cin >> b[i]; 18 | auto c = lcm_convolution(a, b); 19 | for (int i = 1; i <= N; ++i) cout << c[i] << (i < N ? " " : "\n"); 20 | } 21 | -------------------------------------------------------------------------------- /test/yosupo/line_add_get_min.cht.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/line_add_get_min" 2 | 3 | #include "../../data-structure/cht/convex_hull_trick_binsearchtree.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(nullptr); 13 | 14 | int N, Q; 15 | cin >> N >> Q; 16 | ConvexHullTrick cht; 17 | for (int i = 0; i < N; ++i) { 18 | ll a, b; 19 | cin >> a >> b; 20 | cht.add(a, b); 21 | } 22 | while (Q--) { 23 | int t; 24 | cin >> t; 25 | if (t == 0) { 26 | ll a, b; 27 | cin >> a >> b; 28 | cht.add(a, b); 29 | } else { 30 | int p; 31 | cin >> p; 32 | cout << cht.get(p) << "\n"; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /test/yosupo/log_of_formal_power_series.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/log_of_formal_power_series" 2 | 3 | #include "../../math/modint.hpp" 4 | #include "../../math/polynomial.cpp" 5 | 6 | #include 7 | using namespace std; 8 | 9 | using mint = Modint<998244353>; 10 | 11 | int main() { 12 | ios_base::sync_with_stdio(false); 13 | cin.tie(nullptr); 14 | 15 | int N; 16 | cin >> N; 17 | Polynomial f(N); 18 | for (int i = 0; i < N; ++i) cin >> f[i]; 19 | auto g = f.log(); 20 | for (int i = 0; i < N; ++i) cout << g[i] << (i < N - 1 ? " " : "\n"); 21 | } 22 | -------------------------------------------------------------------------------- /test/yosupo/longest_common_substring.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/longest_common_substring" 2 | 3 | #include "../../string/longest_common_substring.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(nullptr); 11 | 12 | string S, T; 13 | cin >> S >> T; 14 | auto [a, b, c, d] = longest_common_substring(S, T); 15 | cout << a << " " << b << " " << c << " " << d << endl; 16 | } 17 | -------------------------------------------------------------------------------- /test/yosupo/longest_increasing_subsequence.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/longest_increasing_subsequence" 2 | 3 | #include "../../dp/lis.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int N; 13 | cin >> N; 14 | vector A(N); 15 | for (auto& x : A) cin >> x; 16 | auto [K, idx] = longest_increasing_subsequence_with_index(A, true); 17 | cout << K << endl; 18 | for (int i = 0; i < K; ++i) cout << idx[i] << (i < K-1 ? " " : "\n"); 19 | } 20 | -------------------------------------------------------------------------------- /test/yosupo/lyndon_factorization.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/lyndon_factorization" 2 | 3 | #include "../../string/lyndon_factorization.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | string S; 13 | cin >> S; 14 | auto res = lyndon_factorization(S); 15 | for (int i = 0; i < (int)res.size(); ++i) 16 | cout << res[i] << (i < (int)res.size() ? " " : "\n"); 17 | } 18 | -------------------------------------------------------------------------------- /test/yosupo/manhattanmst.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/manhattanmst" 2 | 3 | #include 4 | 5 | #include "../../graph/manhattan_mst.hpp" 6 | 7 | using namespace std; 8 | using ll = long long; 9 | 10 | int main() { 11 | int N; 12 | cin >> N; 13 | vector> pts(N); 14 | for (auto& x : pts) cin >> x.first >> x.second; 15 | auto [weight, edges] = manhattan_mst(pts); 16 | cout << weight << endl; 17 | for (auto [u, v] : edges) { 18 | cout << u << " " << v << "\n"; 19 | } 20 | } -------------------------------------------------------------------------------- /test/yosupo/matrix_det.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/matrix_det" 2 | 3 | #include 4 | 5 | #include "../../math/linalg/matrix.hpp" 6 | #include "../../math/modint.hpp" 7 | using namespace std; 8 | 9 | using mint = Modint<998244353>; 10 | 11 | int main() { 12 | ios_base::sync_with_stdio(false); 13 | cin.tie(nullptr); 14 | 15 | int N; 16 | cin >> N; 17 | Matrix a(N); 18 | for (int i = 0; i < N; ++i) { 19 | for (int j = 0; j < N; ++j) cin >> a[i][j]; 20 | } 21 | cout << a.det() << endl; 22 | } 23 | -------------------------------------------------------------------------------- /test/yosupo/matrix_product.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/matrix_product" 2 | 3 | #include 4 | 5 | #include "../../math/linalg/matrix.hpp" 6 | #include "../../math/modint.hpp" 7 | using namespace std; 8 | 9 | using mint = Modint<998244353>; 10 | 11 | int main() { 12 | ios_base::sync_with_stdio(false); 13 | cin.tie(nullptr); 14 | 15 | int N, M, K; 16 | cin >> N >> M >> K; 17 | Matrix A(N, M), B(M, K); 18 | for (int i = 0; i < N; ++i) 19 | for (int j = 0; j < M; ++j) cin >> A[i][j]; 20 | for (int i = 0; i < M; ++i) 21 | for (int j = 0; j < K; ++j) cin >> B[i][j]; 22 | auto C = A * B; 23 | for (int i = 0; i < N; ++i) { 24 | for (int j = 0; j < K; ++j) cout << C[i][j] << (j < K - 1 ? " " : "\n"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/yosupo/matrix_rank.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/matrix_rank" 2 | 3 | #include 4 | 5 | #include "../../math/linalg/matrix.hpp" 6 | #include "../../math/modint.hpp" 7 | using namespace std; 8 | 9 | using mint = Modint<998244353>; 10 | 11 | int main() { 12 | ios_base::sync_with_stdio(false); 13 | cin.tie(nullptr); 14 | 15 | int N, M; 16 | cin >> N >> M; 17 | Matrix A(N, M); 18 | for (int i = 0; i < N; ++i) 19 | for (int j = 0; j < M; ++j) cin >> A[i][j]; 20 | cout << A.rank() << endl; 21 | } 22 | -------------------------------------------------------------------------------- /test/yosupo/maximum_independent_set.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/maximum_independent_set" 2 | 3 | #include "../../graph/maximum_independent_set.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(nullptr); 11 | 12 | int N, M; 13 | cin >> N >> M; 14 | vector> G(N); 15 | for (int i = 0; i < M; ++i) { 16 | int u, v; 17 | cin >> u >> v; 18 | G[u].push_back(v); 19 | G[v].push_back(u); 20 | } 21 | auto ans = maximum_independent_set(G); 22 | cout << ans.size() << endl; 23 | for (int i = 0; i < ans.size(); ++i) cout << ans[i] << (i < ans.size() - 1 ? " " : "\n"); 24 | } 25 | -------------------------------------------------------------------------------- /test/yosupo/min_plus_convolution_convex_arbitrary.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "https://judge.yosupo.jp/problem/min_plus_convolution_convex_arbitrary" 3 | 4 | #include 5 | 6 | #include "../../convolution/convex_min_plus_convolution.hpp" 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int N, M; 14 | cin >> N >> M; 15 | vector a(N), b(M); 16 | for (auto& x : a) cin >> x; 17 | for (auto& x : b) cin >> x; 18 | auto c = convex_min_plus_convolution(b, a); 19 | for (int i = 0; i < N + M - 1; ++i) 20 | cout << c[i] << (i < N + M - 2 ? " " : "\n"); 21 | } 22 | -------------------------------------------------------------------------------- /test/yosupo/montmort_number_mod.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/montmort_number_mod" 2 | 3 | #include "../../math/arbitrary_modint.hpp" 4 | #include "../../math/montmort.cpp" 5 | 6 | #include 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int N, M; 14 | cin >> N >> M; 15 | using mint = ArbitraryModint; 16 | mint::set_mod(M); 17 | vector ans = montmort_table(N); 18 | for (int i = 1; i <= N; ++i) cout << ans[i] << (i < N ? " " : "\n"); 19 | } -------------------------------------------------------------------------------- /test/yosupo/nim_product_64.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/nim_product_64" 2 | 3 | #include "../../math/nimber.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | #define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i) 9 | #define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i) 10 | #define all(x) begin(x), end(x) 11 | template bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; } 12 | template bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; } 13 | 14 | int main() { 15 | ios_base::sync_with_stdio(false); 16 | cin.tie(nullptr); 17 | cout << fixed << setprecision(15); 18 | 19 | int T; 20 | cin >> T; 21 | while (T--) { 22 | Nimber A, B; 23 | cin >> A >> B; 24 | cout << A*B << "\n"; 25 | } 26 | } -------------------------------------------------------------------------------- /test/yosupo/number_of_substrings.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/number_of_substrings" 2 | 3 | #include 4 | 5 | #include "../../string/lcp_array.hpp" 6 | #include "../../string/suffix_array.hpp" 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(0); 12 | 13 | string S; 14 | cin >> S; 15 | int N = S.size(); 16 | auto sa = suffix_array(S); 17 | auto lcp = lcp_array(S, sa); 18 | long long ans = 1LL * N * (N + 1) / 2; 19 | for (int i = 0; i < lcp.size(); ++i) ans -= lcp[i]; 20 | cout << ans << endl; 21 | } -------------------------------------------------------------------------------- /test/yosupo/partition_function.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/partition_function" 2 | 3 | #include "../../math/partition_function.hpp" 4 | #include "../../math/modint.hpp" 5 | 6 | #include 7 | using namespace std; 8 | using ll = long long; 9 | 10 | using mint = Modint<998244353>; 11 | 12 | int main() { 13 | ios_base::sync_with_stdio(false); 14 | cin.tie(nullptr); 15 | 16 | int N; 17 | cin >> N; 18 | auto ans = partition_function_table(N); 19 | for (int i = 0; i <= N; ++i) cout << ans[i] << (i < N ? " " : "\n"); 20 | } -------------------------------------------------------------------------------- /test/yosupo/persistent_queue.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/persistent_queue" 2 | 3 | #include "../../data-structure/persistent_queue.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(nullptr); 11 | 12 | int Q; 13 | cin >> Q; 14 | PersistentQueue init; 15 | vector> ver(Q); 16 | for (int i = 0; i < Q; ++i) { 17 | int q, t; 18 | cin >> q >> t; 19 | if (q == 0) { 20 | int x; 21 | cin >> x; 22 | if (t == -1) 23 | ver[i] = init.push(x); 24 | else 25 | ver[i] = ver[t].push(x); 26 | } else { 27 | cout << ver[t].front() << "\n"; 28 | ver[i] = ver[t].pop(); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /test/yosupo/persistent_unionfind.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/persistent_unionfind" 2 | 3 | #include "../../data-structure/unionfind/persistent_union_find.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(nullptr); 11 | 12 | int N, Q; 13 | cin >> N >> Q; 14 | PersistentUnionFind init(N); 15 | vector ver(Q); 16 | for (int i = 0; i < Q; ++i) { 17 | int t, k, u, v; 18 | cin >> t >> k >> u >> v; 19 | if (t == 0) { 20 | if (k == -1) ver[i] = init.unite(u, v); 21 | else ver[i] = ver[k].unite(u, v); 22 | } else { 23 | int b; 24 | if (k == -1) b = init.same(u, v); 25 | else b = ver[k].same(u, v); 26 | cout << b << "\n"; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /test/yosupo/pow_of_formal_power_series.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/pow_of_formal_power_series" 2 | 3 | #include "../../math/modint.hpp" 4 | #include "../../math/polynomial.cpp" 5 | 6 | #include 7 | using namespace std; 8 | using ll = long long; 9 | 10 | using mint = Modint<998244353>; 11 | 12 | int main() { 13 | ios_base::sync_with_stdio(false); 14 | cin.tie(nullptr); 15 | 16 | int N; 17 | ll M; 18 | cin >> N >> M; 19 | Polynomial f(N); 20 | for (int i = 0; i < N; ++i) cin >> f[i]; 21 | auto g = f.pow(M); 22 | g.resize(N); 23 | for (int i = 0; i < N; ++i) cout << g[i] << (i < N - 1 ? " " : "\n"); 24 | } 25 | -------------------------------------------------------------------------------- /test/yosupo/pow_of_matrix.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/pow_of_matrix" 2 | 3 | #include 4 | 5 | #include "../../math/linalg/matrix.hpp" 6 | #include "../../math/modint.hpp" 7 | using namespace std; 8 | 9 | using mint = Modint<998244353>; 10 | 11 | int main() { 12 | ios_base::sync_with_stdio(false); 13 | cin.tie(nullptr); 14 | 15 | int N; 16 | long long K; 17 | cin >> N >> K; 18 | Matrix a(N); 19 | for (int i = 0; i < N; ++i) { 20 | for (int j = 0; j < N; ++j) cin >> a[i][j]; 21 | } 22 | a = a.pow(K); 23 | for (int i = 0; i < N; ++i) { 24 | for (int j = 0; j < N; ++j) cout << a[i][j] << (j < N - 1 ? " " : "\n"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/yosupo/primality_test.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/primality_test" 2 | 3 | #include 4 | 5 | #include "../../math/number-theory/fast_prime.hpp" 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int Q; 14 | cin >> Q; 15 | while (Q--) { 16 | long long N; 17 | cin >> N; 18 | cout << (fast_prime::is_prime(N) ? "Yes" : "No") << "\n"; 19 | } 20 | } -------------------------------------------------------------------------------- /test/yosupo/primitive_root.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/primitive_root" 2 | 3 | #include "../../math/number-theory/primitive_root.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int Q; 14 | cin >> Q; 15 | while (Q--) { 16 | long long p; 17 | cin >> p; 18 | cout << primitive_root(p) << "\n"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/yosupo/product_of_polynomial_sequence.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/product_of_polynomial_sequence" 2 | 3 | #include "../../math/product_of_polynomial_sequence.hpp" 4 | 5 | #include 6 | 7 | #include "../../math/modint.hpp" 8 | #include "../../math/polynomial.cpp" 9 | 10 | using namespace std; 11 | 12 | using mint = Modint<998244353>; 13 | 14 | int main() { 15 | ios_base::sync_with_stdio(false); 16 | cin.tie(0); 17 | 18 | int N; 19 | cin >> N; 20 | vector> ps(N); 21 | for (int i = 0; i < N; ++i) { 22 | int d; 23 | cin >> d; 24 | ps[i].resize(d + 1); 25 | for (auto& x : ps[i]) cin >> x; 26 | } 27 | auto ans = product_of_polynomial_sequence(ps); 28 | for (int i = 0; i < (int)ans.size(); ++i) 29 | cout << ans[i] << (i < (int)ans.size() - 1 ? " " : "\n"); 30 | } -------------------------------------------------------------------------------- /test/yosupo/range_kth_smallest.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/range_kth_smallest" 2 | 3 | #include 4 | 5 | #include "../../data-structure/wavelet_matrix.hpp" 6 | 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(0); 12 | 13 | int N, Q; 14 | cin >> N >> Q; 15 | vector a(N); 16 | for (int i = 0; i < N; ++i) cin >> a[i]; 17 | WaveletMatrix wm(a); 18 | for (int i = 0; i < Q; ++i) { 19 | int l, r, k; 20 | cin >> l >> r >> k; 21 | cout << wm.quantile(l, r, k) << "\n"; 22 | } 23 | } -------------------------------------------------------------------------------- /test/yosupo/range_reverse_range_sum.splay_tree.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/range_reverse_range_sum" 2 | 3 | #include 4 | 5 | #include "../../data-structure/bst/splay_tree.hpp" 6 | using namespace std; 7 | 8 | struct AddMonoid { 9 | using T = long long; 10 | static T id() { return 0; } 11 | static T op(T a, T b) { return a + b; } 12 | }; 13 | 14 | int main() { 15 | ios_base::sync_with_stdio(false); 16 | cin.tie(0); 17 | 18 | int N, Q; 19 | cin >> N >> Q; 20 | SplayTree st; 21 | for (int i = 0; i < N; ++i) { 22 | long long x; 23 | cin >> x; 24 | st.push_back(x); 25 | } 26 | for (int i = 0; i < Q; i++) { 27 | int t, l, r; 28 | cin >> t >> l >> r; 29 | if (t == 0) { 30 | st.reverse(l, r); 31 | } else { 32 | cout << st.fold(l, r) << "\n"; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /test/yosupo/range_reverse_range_sum.treap.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/range_reverse_range_sum" 2 | 3 | #include 4 | 5 | #include "../../data-structure/bst/treap.hpp" 6 | using namespace std; 7 | 8 | struct AddMonoid { 9 | using T = long long; 10 | static T id() { return 0; } 11 | static T op(T a, T b) { return a + b; } 12 | }; 13 | 14 | int main() { 15 | ios_base::sync_with_stdio(false); 16 | cin.tie(0); 17 | 18 | int N, Q; 19 | cin >> N >> Q; 20 | Treap st; 21 | for (int i = 0; i < N; ++i) { 22 | long long x; 23 | cin >> x; 24 | st.push_back(x); 25 | } 26 | for (int i = 0; i < Q; i++) { 27 | int t, l, r; 28 | cin >> t >> l >> r; 29 | if (t == 0) { 30 | st.reverse(l, r); 31 | } else { 32 | cout << st.fold(l, r) << "\n"; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /test/yosupo/rectangle_sum.range_tree.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/rectangle_sum" 2 | 3 | #include 4 | 5 | #include "../../data-structure/range_tree.hpp" 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int N, Q; 14 | cin >> N >> Q; 15 | vector> pts; 16 | for (int i = 0; i < N; ++i) { 17 | int x, y, w; 18 | cin >> x >> y >> w; 19 | pts.push_back({x, y, w}); 20 | } 21 | RangeTree rt(pts); 22 | for (int i = 0; i < Q; ++i) { 23 | int l, d, r, u; 24 | cin >> l >> d >> r >> u; 25 | cout << rt.fold(l, r, d, u) << "\n"; 26 | } 27 | } -------------------------------------------------------------------------------- /test/yosupo/rooted_tree_isomorphism_classification.ahu.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/rooted_tree_isomorphism_classification" 2 | 3 | #include "../../tree/tree_isomorphism.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int N; 13 | cin >> N; 14 | vector> G(N); 15 | for (int i = 1; i < N; ++i) { 16 | int p; 17 | cin >> p; 18 | G[p].push_back(i); 19 | } 20 | TreeEncoder enc; 21 | auto val = enc.encode(G, 0); 22 | cout << *max_element(val.begin(), val.end()) + 1 << endl; 23 | for (int i = 0; i < N; ++i) cout << val[i] << (i < N - 1 ? " " : "\n"); 24 | } -------------------------------------------------------------------------------- /test/yosupo/rooted_tree_isomorphism_classification.hash.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM \ 2 | "https://judge.yosupo.jp/problem/rooted_tree_isomorphism_classification" 3 | 4 | #include 5 | 6 | #include "../../misc/compress.hpp" 7 | #include "../../tree/tree_isomorphism.hpp" 8 | using namespace std; 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(0); 13 | 14 | int N; 15 | cin >> N; 16 | vector> G(N); 17 | for (int i = 1; i < N; ++i) { 18 | int p; 19 | cin >> p; 20 | G[p].push_back(i); 21 | } 22 | TreeHasher hash; 23 | auto val = hash.hash_subtrees(G, 0); 24 | Compress comp(val); 25 | auto val2 = comp.compress(val); 26 | cout << comp.size() << endl; 27 | for (int i = 0; i < N; ++i) cout << val2[i] << (i < N - 1 ? " " : "\n"); 28 | } -------------------------------------------------------------------------------- /test/yosupo/runenumerate.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/runenumerate" 2 | 3 | #include "../../string/enumerate_runs.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | string S; 13 | cin >> S; 14 | auto runs = enumerate_runs(S); 15 | vector> ans; 16 | set> used; 17 | for (int p = 1; p <= S.size(); ++p) { 18 | for (auto [l, r] : runs[p]) { 19 | if (!used.count({l, r})) { 20 | used.insert({l, r}); 21 | ans.push_back({p, l, r}); 22 | } 23 | } 24 | } 25 | sort(ans.begin(), ans.end()); 26 | cout << ans.size() << endl; 27 | for (auto [t, l, r] : ans) { 28 | cout << t << " " << l << " " << r << "\n"; 29 | } 30 | } -------------------------------------------------------------------------------- /test/yosupo/scc.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/scc" 2 | 3 | #include "../../graph/scc.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int N, M; 14 | cin >> N >> M; 15 | vector> G(N); 16 | for (int i = 0; i < M; ++i) { 17 | int a, b; 18 | cin >> a >> b; 19 | G[a].push_back(b); 20 | } 21 | auto comp = scc(G); 22 | int n = *max_element(comp.begin(), comp.end()) + 1; 23 | vector> comps(n); 24 | for (int i = 0; i < N; ++i) comps[comp[i]].push_back(i); 25 | cout << n << "\n"; 26 | for (int i = 0; i < n; ++i) { 27 | cout << comps[i].size(); 28 | for (int v : comps[i]) cout << " " << v; 29 | cout << "\n"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/yosupo/set_xor_min.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/set_xor_min" 2 | 3 | #include 4 | 5 | #include "../../data-structure/binary_trie.hpp" 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | BinaryTrie bt; 14 | int Q; 15 | cin >> Q; 16 | while (Q--) { 17 | int t, x; 18 | cin >> t >> x; 19 | if (t == 0) { 20 | if (!bt.count(x)) bt.insert(x); 21 | } 22 | if (t == 1) { 23 | if (bt.count(x)) bt.erase(x); 24 | } 25 | if (t == 2) { 26 | cout << bt.min_element(x) << "\n"; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /test/yosupo/sharp_p_subset_sum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/sharp_p_subset_sum" 2 | 3 | #include 4 | 5 | #include "../../math/count_subset_sum.hpp" 6 | #include "../../math/modint.hpp" 7 | 8 | using mint = Modint<998244353>; 9 | 10 | using namespace std; 11 | using ll = long long; 12 | 13 | int main() { 14 | int N, T; 15 | cin >> N >> T; 16 | vector s(N); 17 | for (auto& x : s) cin >> x; 18 | auto ans = count_subset_sum(s, T); 19 | 20 | for (int i = 1; i <= T; ++i) { 21 | cout << ans[i] << (i < T ? " " : "\n"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/yosupo/sqrt_mod.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/sqrt_mod" 2 | 3 | #include "../../math/number-theory/mod_arithmetic.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(nullptr); 11 | 12 | int T; 13 | cin >> T; 14 | for (int i = 0; i < T; ++i) { 15 | int Y, P; 16 | cin >> Y >> P; 17 | cout << mod_sqrt(Y, P) << "\n"; 18 | } 19 | } -------------------------------------------------------------------------------- /test/yosupo/static_convex_hull.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/static_convex_hull" 2 | 3 | #include 4 | 5 | #include "../../geometry/convex_hull.hpp" 6 | #include "../../geometry/geometry.hpp" 7 | using namespace std; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(0); 12 | 13 | int T; 14 | cin >> T; 15 | while (T--) { 16 | int N; 17 | cin >> N; 18 | vector pts(N); 19 | for (auto& p : pts) cin >> p; 20 | auto conv = convex_hull(pts); 21 | cout << conv.size() << "\n"; 22 | for (auto& p : conv) 23 | cout << (int)p.real() << " " << (int)p.imag() << "\n"; 24 | } 25 | } -------------------------------------------------------------------------------- /test/yosupo/static_range_frequency.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/static_range_frequency" 2 | 3 | #include 4 | 5 | #include "../../data-structure/wavelet_matrix.hpp" 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int N, Q; 13 | cin >> N >> Q; 14 | if (N == 0) { 15 | while (Q--) cout << 0 << "\n"; 16 | return 0; 17 | } 18 | vector a(N); 19 | for (auto& x : a) cin >> x; 20 | WaveletMatrix wm(a); 21 | while (Q--) { 22 | int l, r, x; 23 | cin >> l >> r >> x; 24 | cout << wm.rank(r, x) - wm.rank(l, x) << "\n"; 25 | } 26 | } -------------------------------------------------------------------------------- /test/yosupo/staticrmq.sqrt_tree.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/staticrmq" 2 | 3 | #include 4 | 5 | #include "../../data-structure/sqrt_tree.hpp" 6 | using namespace std; 7 | 8 | struct MinSemigroup { 9 | using T = int; 10 | static T op(T a, T b) { return min(a, b); } 11 | }; 12 | 13 | int main() { 14 | ios_base::sync_with_stdio(false); 15 | cin.tie(0); 16 | 17 | int N, Q; 18 | cin >> N >> Q; 19 | vector a(N); 20 | for (auto& x : a) cin >> x; 21 | SqrtTree st(a); 22 | while (Q--) { 23 | int l, r; 24 | cin >> l >> r; 25 | cout << st.fold(l, r) << "\n"; 26 | } 27 | } -------------------------------------------------------------------------------- /test/yosupo/staticrmq.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/staticrmq" 2 | 3 | #include 4 | 5 | #include "../../data-structure/disjoint_sparse_table.hpp" 6 | using namespace std; 7 | 8 | struct MinMonoid { 9 | using T = int; 10 | static T id() { return (1u << 31) - 1; } 11 | static T op(T a, T b) { return min(a, b); } 12 | }; 13 | 14 | int main() { 15 | ios_base::sync_with_stdio(false); 16 | cin.tie(0); 17 | 18 | int N, Q; 19 | cin >> N >> Q; 20 | vector a(N); 21 | for (int i = 0; i < N; i++) cin >> a[i]; 22 | DisjointSparseTable st(a); 23 | for (int i = 0; i < Q; i++) { 24 | int l, r; 25 | cin >> l >> r; 26 | cout << st.fold(l, r) << "\n"; 27 | } 28 | } -------------------------------------------------------------------------------- /test/yosupo/stirling_number_of_the_first_kind.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/stirling_number_of_the_first_kind" 2 | 3 | #include "../../math/modint.hpp" 4 | #include "../../math/stirling_first.hpp" 5 | 6 | #include 7 | using namespace std; 8 | using ll = long long; 9 | 10 | using mint = Modint<998244353>; 11 | 12 | int main() { 13 | int N; 14 | cin >> N; 15 | auto ans = stirling_first_table(N); 16 | for (int i = 0; i <= N; ++i) { 17 | cout << ans[i] << (i < N ? " " : "\n"); 18 | } 19 | } -------------------------------------------------------------------------------- /test/yosupo/stirling_number_of_the_second_kind.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/stirling_number_of_the_second_kind" 2 | 3 | 4 | #include "../../math/modint.hpp" 5 | #include "../../math/stirling_second.hpp" 6 | 7 | #include 8 | using namespace std; 9 | using ll = long long; 10 | 11 | using mint = Modint<998244353>; 12 | 13 | int main() { 14 | int N; 15 | cin >> N; 16 | auto ans = stirling_second_table(N); 17 | for (int i = 0; i <= N; ++i) { 18 | cout << ans[i] << (i < N ? " " : "\n"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/yosupo/subset_convolution.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/subset_convolution" 2 | 3 | #include "../../math/set/subset_convolution.hpp" 4 | 5 | #include 6 | 7 | #include "../../math/modint.hpp" 8 | using namespace std; 9 | using ll = long long; 10 | 11 | using mint = Modint<998244353>; 12 | 13 | int main() { 14 | int N; 15 | cin >> N; 16 | vector a(1 << N), b(1 << N); 17 | for (int i = 0; i < 1 << N; ++i) cin >> a[i]; 18 | for (int i = 0; i < 1 << N; ++i) cin >> b[i]; 19 | auto c = subset_convolution(a, b); 20 | for (int i = 0; i < 1 << N; ++i) 21 | cout << c[i] << (i < (1 << N) - 1 ? " " : "\n"); 22 | } 23 | -------------------------------------------------------------------------------- /test/yosupo/suffixarray.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/suffixarray" 2 | 3 | #include "../../string/suffix_array.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | string S; 13 | cin >> S; 14 | auto sa = suffix_array(S); 15 | for (int i = 0; i < S.size(); ++i) { 16 | cout << sa[i] << (i < S.size() - 1 ? " " : "\n"); 17 | } 18 | } -------------------------------------------------------------------------------- /test/yosupo/sum_of_floor_of_linear.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/sum_of_floor_of_linear" 2 | 3 | #include "../../math/number-theory/floor_sum.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int T; 13 | cin >> T; 14 | while (T--) { 15 | int N, M, A, B; 16 | cin >> N >> M >> A >> B; 17 | cout << floor_sum(N, M, A, B) << "\n"; 18 | } 19 | } -------------------------------------------------------------------------------- /test/yosupo/sum_of_totient_function.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/sum_of_totient_function" 2 | 3 | #include 4 | 5 | #include "../../math/modint.hpp" 6 | #include "../../math/number-theory/euler_totient.hpp" 7 | using namespace std; 8 | 9 | using mint = Modint<998244353>; 10 | 11 | int main() { 12 | ios_base::sync_with_stdio(false); 13 | cin.tie(nullptr); 14 | 15 | long long N; 16 | cin >> N; 17 | auto [small, large] = totient_summatory_table(N); 18 | mint ans = large[1]; 19 | cout << ans << endl; 20 | } -------------------------------------------------------------------------------- /test/yosupo/tetration_mod.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/tetration_mod" 2 | 3 | #include "../../math/number-theory/mod_arithmetic.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int T; 14 | cin >> T; 15 | while (T--) { 16 | int A, B, M; 17 | cin >> A >> B >> M; 18 | cout << mod_tetration(A, B, M) << "\n"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/yosupo/tree_diameter.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/tree_diameter" 2 | 3 | #include "../../tree/tree_diameter.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | 9 | template 10 | ostream& operator<<(ostream& os, const vector& v) { 11 | for (int i = 0; i < (int)v.size(); ++i) cout << v[i] << " "; 12 | return os; 13 | } 14 | 15 | int main() { 16 | ios_base::sync_with_stdio(false); 17 | cin.tie(nullptr); 18 | 19 | int N; 20 | cin >> N; 21 | vector>> G(N); 22 | for (int i = 0; i < N - 1; ++i) { 23 | int a, b, c; 24 | cin >> a >> b >> c; 25 | G[a].push_back({b, c}); 26 | G[b].push_back({a, c}); 27 | } 28 | auto ans = tree_diameter(G); 29 | cout << ans.first << " " << ans.second.size() << endl; 30 | cout << ans.second << endl; 31 | } -------------------------------------------------------------------------------- /test/yosupo/two_sat.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/two_sat" 2 | 3 | #include "../../sat/twosat.hpp" 4 | 5 | #include 6 | using namespace std; 7 | using ll = long long; 8 | 9 | int main() { 10 | string _p, _cnf; 11 | int N, M; 12 | cin >> _p >> _cnf >> N >> M; 13 | vector> clauses; 14 | for (int i = 0; i < M; i++) { 15 | int a, b, _c; 16 | cin >> a >> b >> _c; 17 | clauses.push_back({abs(a) - 1, (a > 0), abs(b) - 1, (b > 0)}); 18 | } 19 | auto ans = two_sat(N, clauses); 20 | if (!ans.empty()) { 21 | cout << "s SATISFIABLE\nv"; 22 | for (int i = 0; i < N; i++) { 23 | cout << " " << (ans[i] ? 1 : -1) * (i + 1); 24 | } 25 | cout << " 0\n"; 26 | } else { 27 | cout << "s UNSATISFIABLE\n"; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/yosupo/unionfind.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/unionfind" 2 | 3 | #include "../../data-structure/unionfind/union_find.hpp" 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int N, Q; 13 | cin >> N >> Q; 14 | UnionFind uf(N); 15 | for (int i = 0; i < Q; i++) { 16 | int t, u, v; 17 | cin >> t >> u >> v; 18 | if (t == 0) uf.unite(u, v); 19 | else cout << uf.same(u, v) << "\n"; 20 | } 21 | } -------------------------------------------------------------------------------- /test/yosupo/zalgorithm.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/zalgorithm" 2 | 3 | #include 4 | 5 | #include "../../string/z_array.hpp" 6 | using namespace std; 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | string S; 13 | cin >> S; 14 | vector z = z_array(S); 15 | for (int i = 0; i < S.size(); ++i) 16 | cout << z[i] << (i < S.size() - 1 ? " " : "\n"); 17 | } -------------------------------------------------------------------------------- /tree/cartesian_tree.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | template 6 | std::vector cartesian_tree(const std::vector& a) { 7 | const int n = a.size(); 8 | std::vector par(n, -1); 9 | std::stack st; 10 | for (int i = 0; i < n; ++i) { 11 | int j = -1; 12 | while (!st.empty() && a[st.top()] >= a[i]) { 13 | j = st.top(); 14 | st.pop(); 15 | } 16 | if (!st.empty()) par[i] = st.top(); 17 | if (j != -1) par[j] = i; 18 | st.push(i); 19 | } 20 | return par; 21 | } -------------------------------------------------------------------------------- /tree/euler_tour.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | /** 5 | * @brief Euler Tour 6 | */ 7 | std::pair, std::vector> euler_tour( 8 | const std::vector>& G, int root) { 9 | std::vector in(G.size()), out(G.size()); 10 | int k = 0; 11 | 12 | auto dfs = [&](auto& dfs, int v, int p) -> void { 13 | in[v] = k++; 14 | for (int c : G[v]) 15 | if (c != p) dfs(dfs, c, v); 16 | out[v] = k; 17 | }; 18 | 19 | dfs(dfs, root, -1); 20 | return {in, out}; 21 | } 22 | --------------------------------------------------------------------------------