├── .bundle └── config ├── .clang-format ├── .gitignore ├── .verify-helper └── config.toml ├── README ├── acted_monoid ├── acted_monoid_combine.hpp ├── acted_monoid_reverse.hpp ├── max2_add.hpp ├── max_add.hpp ├── max_assign.hpp ├── max_max.hpp ├── max_min.hpp ├── maxmaxcnt2_add.hpp ├── maxmaxcnt_add.hpp ├── min2_add.hpp ├── min_add.hpp ├── min_assign.hpp ├── min_max.hpp ├── min_min.hpp ├── minmax_add.hpp ├── minmax_assign.hpp ├── minmax_mul.hpp ├── minmincnt2_add.hpp ├── minmincnt_add.hpp ├── rollinghash_add.hpp ├── sum_add.hpp ├── sum_affine.hpp ├── sum_assign.hpp ├── sum_mul.hpp ├── summax_add.hpp ├── summax_assign.hpp ├── summin_add.hpp ├── summin_assign.hpp ├── summinmax_add.hpp ├── summinmax_assign.hpp └── summinmax_mul.hpp ├── acted_set └── from_monoid.hpp ├── all.hpp ├── all2.hpp ├── cpp11 ├── all.hpp ├── bit.hpp ├── bsearch.hpp ├── compatibility.hpp ├── dsu.hpp ├── io.hpp ├── isqrt.hpp ├── miller_rabin.hpp ├── mint.hpp ├── montgomery.hpp ├── pdqsort.hpp ├── pollard_rho.hpp ├── prime_sieve.hpp ├── radix_sort.hpp ├── rng.hpp ├── rolling_hash.hpp ├── template.hpp ├── timer.hpp └── types.hpp ├── date.hpp ├── ds ├── beats_summax_addchmin.hpp ├── beats_summin_addchmax.hpp ├── beats_summinmax_addchminchmax.hpp ├── bit.hpp ├── bit_vector.hpp ├── bitset.hpp ├── counter.hpp ├── deque.hpp ├── disjoint_sparse_table.hpp ├── dual_fenwicktree.hpp ├── dual_kdtree_monoid.hpp ├── dual_segtree.hpp ├── dynamic_array.hpp ├── dynamic_lazy_segtree.hpp ├── dynamic_segtree.hpp ├── dynamic_segtree_sparse.hpp ├── dynamic_unionfind.hpp ├── fastset.hpp ├── fenwicktree.hpp ├── fenwicktree_01.hpp ├── hashmap.hpp ├── hashset.hpp ├── index_compression.hpp ├── kdtree.hpp ├── kdtree_acted_monoid.hpp ├── kdtree_monoid.hpp ├── lazy_segtree.hpp ├── meldable_heap.hpp ├── offline │ ├── mo.hpp │ └── mo_dual_offline.hpp ├── range_add_range_sum.hpp ├── range_assignment_segtree.hpp ├── rectangle_union.hpp ├── removable_queue.hpp ├── rollback_array.hpp ├── rollback_unionfind.hpp ├── segtree.hpp ├── segtree_beats.hpp ├── sortable_array.hpp ├── sparse_table.hpp ├── sqrtfenwicktree.hpp ├── sqrtfenwicktree_01.hpp ├── static_range_product.hpp ├── static_rmq.hpp ├── swag.hpp ├── unionfind.hpp ├── unit_prod.hpp ├── wavelet_matrix.hpp ├── weighted_unionfind.hpp └── wide_segtree.hpp ├── ds2d └── cumsum2d.hpp ├── enumerate ├── combinations.hpp ├── permutations.hpp └── xor_range.hpp ├── flow └── maxflow.hpp ├── graph ├── K_shortest_path.hpp ├── K_shortest_walk.hpp ├── auxiliary_tree.hpp ├── base.hpp ├── bellmanford.hpp ├── bfs01.hpp ├── bipartite_vertex_coloring.hpp ├── block_cut_tree.hpp ├── centroid_decomposition.hpp ├── contour_query_range.hpp ├── dijkstra.hpp ├── dual_tree_monoid.hpp ├── euler_walk.hpp ├── fast_lca.hpp ├── find_centroids.hpp ├── find_cycle.hpp ├── floyd.hpp ├── grid_bfs.hpp ├── hash_tree.hpp ├── kruskal.hpp ├── lazy_tree_monoid.hpp ├── manhattan_mst.hpp ├── minimum_cost_arborescence.hpp ├── minimum_hamiltonian_cycle.hpp ├── negative_cycle.hpp ├── reachability_bitset.hpp ├── restore_path.hpp ├── static_tree_monoid.hpp ├── strongly_connected_component.hpp ├── topological_sort.hpp ├── tree.hpp ├── tree_abelgroup.hpp ├── tree_all_distances.hpp ├── tree_monoid.hpp ├── tree_monoid_base.hpp ├── two_edge_component.hpp ├── twosat.hpp ├── unicyclic.hpp ├── utility.hpp └── vs_to_es.hpp ├── io ├── dummy.hpp ├── freadreader.hpp ├── fwritewriter.hpp ├── io.hpp ├── io2.hpp └── mmapreader.hpp ├── linalg ├── characteristic_poly.hpp ├── frobenius.hpp ├── matrix_det.hpp ├── matrix_inv.hpp ├── matrix_mul.hpp ├── matrix_pow.hpp ├── transpose.hpp └── vector_space.hpp ├── math ├── bigint.hpp ├── binary_search.hpp ├── discrete_log.hpp ├── divisors.hpp ├── euler_phi.hpp ├── exgcd.hpp ├── factorize.hpp ├── fixpoint.hpp ├── fraction.hpp ├── gcd.hpp ├── icbrt.hpp ├── inth_root.hpp ├── isqrt.hpp ├── lcm.hpp ├── lpf_table.hpp ├── mobius_table.hpp ├── mod_inverse.hpp ├── power.hpp ├── prime │ ├── counting.hpp │ ├── sieve.hpp │ └── test.hpp ├── primitive_root.hpp ├── primitive_root_constexpr.hpp └── zeta.hpp ├── modint ├── all_inverse.hpp ├── barrett.hpp ├── barrett_reduction.hpp ├── binomial.hpp ├── mint61.hpp ├── mod_log.hpp ├── mod_sqrt.hpp ├── modint_common.hpp ├── montgomery.hpp └── montgomery_reduction.hpp ├── monoid ├── add.hpp ├── add_array.hpp ├── addmax.hpp ├── addmin.hpp ├── addminmax.hpp ├── affine.hpp ├── and.hpp ├── assign.hpp ├── gcd.cpp ├── max.hpp ├── max2.hpp ├── max_idx.hpp ├── maxmaxcnt.hpp ├── maxmaxcnt2.hpp ├── merge_vector_space.hpp ├── min.hpp ├── min2.hpp ├── min_idx.hpp ├── minmax.hpp ├── minmincnt.hpp ├── minmincnt2.hpp ├── monoid_combine.hpp ├── monoid_reverse.hpp ├── moore.hpp ├── mul.hpp ├── or.hpp ├── rollinghash.hpp └── xor.hpp ├── poly ├── arbitrary_ntt.hpp ├── convolution.hpp ├── convolution_fft.hpp ├── convolution_huge.hpp ├── convolution_karatsuba.hpp ├── convolution_naive.hpp ├── convolution_square.hpp ├── fft.hpp ├── lagrange_interpolate_iota.hpp ├── middle_product.hpp ├── ntt.hpp └── ntt_avx2.hpp ├── random ├── base.hpp ├── hash.hpp └── shuffle.hpp ├── seed.hpp ├── seq └── longest_increasing_subsequence.hpp ├── string ├── count_subsequence.hpp ├── is_substring.hpp ├── longest_common_subsequence.hpp ├── rolling_hash.hpp ├── rolling_hash_2d.hpp ├── split.hpp ├── suffix_array.hpp ├── trie.hpp ├── wildcard_pattern_matching.hpp └── zalgorithm.hpp ├── template.hpp ├── test ├── aoj │ ├── ALDS1_10_C.test.cpp │ ├── DPL_2_A.test.cpp │ ├── DSL_1_A.test.cpp │ ├── DSL_1_B.test.cpp │ ├── DSL_2_A.test.cpp │ ├── DSL_2_B.test.cpp │ ├── DSL_2_C.test.cpp │ ├── DSL_2_D.test.cpp │ ├── DSL_2_E.ft.test.cpp │ ├── DSL_2_E.test.cpp │ ├── DSL_2_F.test.cpp │ ├── DSL_2_G.ft.test.cpp │ ├── DSL_2_G.test.cpp │ ├── DSL_2_H.test.cpp │ ├── DSL_2_I.test.cpp │ ├── DSL_3_A.test.cpp │ ├── DSL_4_A.test.cpp │ ├── GRL_1_A.test.cpp │ ├── GRL_1_B.test.cpp │ ├── GRL_1_C.test.cpp │ ├── GRL_2_A.test.cpp │ ├── GRL_2_B.pool.test.cpp │ ├── GRL_2_B.test.cpp │ ├── GRL_3_A.test.cpp │ ├── GRL_3_B.test.cpp │ ├── GRL_3_C.test.cpp │ ├── GRL_4_A.test.cpp │ ├── GRL_4_B.test.cpp │ ├── GRL_5_A.test.cpp │ ├── GRL_5_B.test.cpp │ ├── GRL_5_C.test.cpp │ ├── GRL_5_D.test.cpp │ ├── GRL_5_E.test.cpp │ ├── GRL_6_A.test.cpp │ ├── ITP1_3_D.test.cpp │ ├── ITP1_9_A.io2.test.cpp │ ├── ITP1_9_A.test.cpp │ ├── NTL_1_A.test.cpp │ ├── NTL_1_B.test.cpp │ ├── NTL_1_C.test.cpp │ ├── NTL_1_D.test.cpp │ ├── NTL_1_E.test.cpp │ ├── NTL_2_A.test.cpp │ ├── NTL_2_B.test.cpp │ ├── NTL_2_C.test.cpp │ ├── NTL_2_D.test.cpp │ ├── NTL_2_E.test.cpp │ └── NTL_2_F.test.cpp ├── atcoder │ ├── abc217_e.test.cpp │ ├── abc237_g.test.cpp │ ├── abc266_f.test.cpp │ ├── abc268_h.test.cpp │ ├── abc294_g.test.cpp │ ├── abc318_g.test.cpp │ ├── abc319_d.test.cpp │ ├── abc324_f.test.cpp │ ├── abc325_e.test.cpp │ ├── abc337_c.test.cpp │ ├── abc339_f.test.cpp │ ├── abc362_f.cpp │ ├── abc362_g.test.cpp │ ├── arc157_a.test.cpp │ ├── past202004_n.test.cpp │ ├── past202004_o.test.cpp │ ├── past202005_m.test.cpp │ ├── past202005_n.test.cpp │ ├── past202010_f.test.cpp │ ├── past202010_h.test.cpp │ └── past202010_m.test.cpp ├── custom │ ├── all_inverse.test.cpp │ ├── bellmanford.1.test.cpp │ ├── convolution_square.avx2.test.cpp │ ├── convolution_square.test.cpp │ ├── date.test.cpp │ ├── dual_kdtree_monoid.test.cpp │ ├── fft.test.cpp │ ├── index_compression.test.cpp │ ├── interval_union.test.cpp │ ├── is_substring.test.cpp │ ├── kdtree_acted_monoid.test.cpp │ ├── kdtree_monoid.test.cpp │ ├── radix_sort.test.cpp │ └── sortable_array.test.cpp └── library_checker │ ├── addition_of_big_integers.test.cpp │ ├── aplusb.test.cpp │ ├── area_of_union_of_rectangles.test.cpp │ ├── associative_array.reserve.test.cpp │ ├── associative_array.test.cpp │ ├── biconnected_components.test.cpp │ ├── binomial_coefficient_prime_mod.no_extend.test.cpp │ ├── binomial_coefficient_prime_mod.test.cpp │ ├── characteristic_polynomial.test.cpp │ ├── convolution_mod.avx2.test.cpp │ ├── convolution_mod.test.cpp │ ├── convolution_mod_1000000007.avx2.test.cpp │ ├── convolution_mod_1000000007.test.cpp │ ├── convolution_mod_large.avx2.test.cpp │ ├── convolution_mod_large.test.cpp │ ├── counting_primes.test.cpp │ ├── cycle_detection.test.cpp │ ├── cycle_detection_undirected.test.cpp │ ├── cycle_detection_undirected_minimal.test.cpp │ ├── deque_operate_all_composite.test.cpp │ ├── directedmst.pool.test.cpp │ ├── directedmst.test.cpp │ ├── discrete_logarithm_mod.test.cpp │ ├── division_of_big_integers.test.cpp │ ├── double_ended_priority_queue.test.cpp │ ├── enumerate_primes.test.cpp │ ├── factorize.test.cpp │ ├── frequency_table_of_tree_distance.0.test.cpp │ ├── frequency_table_of_tree_distance.2.test.cpp │ ├── frequency_table_of_tree_distance.test.cpp │ ├── inverse_matrix.test.cpp │ ├── jump_on_tree.test.cpp │ ├── k_shortest_walk.pool.test.cpp │ ├── k_shortest_walk.test.cpp │ ├── kth_root_integer.test.cpp │ ├── lca.fast.test.cpp │ ├── lca.lid.test.cpp │ ├── lca.test.cpp │ ├── longest_increasing_subsequence.test.cpp │ ├── manhattanmst.test.cpp │ ├── many_aplusb.test.cpp │ ├── many_aplusb_128bit.test.cpp │ ├── matrix_det.test.cpp │ ├── matrix_det_arbitrary_mod.test.cpp │ ├── matrix_product.test.cpp │ ├── matrix_product_mod_2.test.cpp │ ├── minimum_spanning_tree.test.cpp │ ├── multiplication_of_big_integers.test.cpp │ ├── number_of_subsequences.test.cpp │ ├── persistent_queue.test.cpp │ ├── persistent_unionfind.pool.test.cpp │ ├── persistent_unionfind.test.cpp │ ├── point_add_range_sum.seg.test.cpp │ ├── point_add_range_sum.test.cpp │ ├── point_add_range_sum.wseg.test.cpp │ ├── point_set_range_composite.dynamic.pool.test.cpp │ ├── point_set_range_composite.dynamic.test.cpp │ ├── point_set_range_composite.test.cpp │ ├── pow_of_matrix.test.cpp │ ├── predecessor_problem.test.cpp │ ├── primality_test.test.cpp │ ├── primitive_root.test.cpp │ ├── queue_operate_all_composite.test.cpp │ ├── range_affine_point_get.test.cpp │ ├── range_affine_range_sum.dynamic.pool.test.cpp │ ├── range_affine_range_sum.dynamic.test.cpp │ ├── range_affine_range_sum.test.cpp │ ├── range_chmin_chmax_add_range_sum.test.cpp │ ├── range_kth_smallest.pseg.pool.test.cpp │ ├── range_kth_smallest.pseg.test.cpp │ ├── range_kth_smallest.pseg_sparse.pool.test.cpp │ ├── range_kth_smallest.pseg_sparse.test.cpp │ ├── range_kth_smallest.test.cpp │ ├── range_set_range_composite.test.cpp │ ├── scc.test.cpp │ ├── shift_of_sampling_points_of_polynomial.test.cpp │ ├── shortest_path.test.cpp │ ├── sort_points_by_argument.test.cpp │ ├── sort_points_by_argument_pdqsort.test.cpp │ ├── sqrt_mod.test.cpp │ ├── static_range_inversions_query.1.test.cpp │ ├── static_range_inversions_query.2.test.cpp │ ├── static_range_inversions_query.3.test.cpp │ ├── static_range_inversions_query.test.cpp │ ├── static_range_sum.test.cpp │ ├── staticrmq.dst.test.cpp │ ├── staticrmq.srp.dst.test.cpp │ ├── staticrmq.srp.test.cpp │ ├── staticrmq.st.test.cpp │ ├── staticrmq.test.cpp │ ├── suffixarray.test.cpp │ ├── tree_diameter.test.cpp │ ├── two_edge_connected_components.test.cpp │ ├── two_sat.test.cpp │ ├── unionfind.test.cpp │ ├── vertex_add_path_sum.abelgroup.test.cpp │ ├── vertex_add_path_sum.test.cpp │ ├── vertex_add_range_contour_sum_on_tree.test.cpp │ ├── vertex_add_subtree_sum.abelgroup.test.cpp │ ├── vertex_add_subtree_sum.test.cpp │ ├── vertex_get_range_contour_add_on_tree.test.cpp │ ├── vertex_set_path_composite.test.cpp │ ├── wildcard_pattern_matching.avx2.test.cpp │ ├── wildcard_pattern_matching.test.cpp │ ├── zalgorithm.test.cpp │ └── zalgorithm_rolling_hash.test.cpp ├── timer.hpp ├── types.hpp └── utility ├── cache.hpp ├── generator.hpp ├── interval_union.hpp ├── itos_table.hpp ├── make_double_width.hpp ├── memory_pool.hpp ├── pbds.hpp ├── pdqsort.hpp ├── radix_sort.hpp └── timer.hpp /.bundle/config: -------------------------------------------------------------------------------- 1 | --- 2 | BUNDLE_PATH: ".vendor/bundle" 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/*.gch -------------------------------------------------------------------------------- /.verify-helper/config.toml: -------------------------------------------------------------------------------- 1 | [[languages.cpp.environments]] 2 | CXX = "g++" 3 | CXXFLAGS = ["-std=c++20", "-O2", "-march=native"] -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 模板库 -------------------------------------------------------------------------------- /acted_monoid/acted_monoid_combine.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/monoid_combine.hpp" 3 | 4 | template 5 | struct ActedMonoid_Combine { 6 | using Monoid_X = Monoid_Combine; 7 | using Monoid_A = std::tuple_element_t<0, std::tuple>; 8 | using X = Monoid_X::value_type; 9 | using A = Monoid_A::value_type; 10 | 11 | static_assert((std::is_same_v && ...)); 12 | static constexpr X act(const X& x, const A& a, int sz) { 13 | return [&](std::index_sequence) -> X { return {AM::act(std::get(x), a, sz)...}; }(std::index_sequence_for{}); 14 | } 15 | }; -------------------------------------------------------------------------------- /acted_monoid/acted_monoid_reverse.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/monoid_reverse.hpp" 3 | 4 | template 5 | struct Acted_Monoid_Reverse { 6 | using Monoid_X = Monoid_Reverse; 7 | using Monoid_A = AM::Monoid_A; 8 | using X = Monoid_X::value_type; 9 | using A = Monoid_A::value_type; 10 | static constexpr X act(const X& x, const A& a, int sz) { return AM::act(x, a, sz); } 11 | }; -------------------------------------------------------------------------------- /acted_monoid/max2_add.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/max2.hpp" 3 | #include "monoid/add.hpp" 4 | 5 | template 6 | struct ActedMonoid_Max2_Add { 7 | using Monoid_X = Monoid_Max2; 8 | using Monoid_A = Monoid_Add; 9 | using X = Monoid_X::value_type; 10 | using A = Monoid_A::value_type; 11 | static constexpr X act(const X& x, const A& a, int) { 12 | return {Max(-inf, x.first + a), Max(-inf, x.second + a)}; 13 | } 14 | }; -------------------------------------------------------------------------------- /acted_monoid/max_add.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/max.hpp" 3 | #include "monoid/add.hpp" 4 | 5 | template 6 | struct ActedMonoid_Max_Add { 7 | using Monoid_X = Monoid_Max; 8 | using Monoid_A = Monoid_Add; 9 | using X = Monoid_X::value_type; 10 | using A = Monoid_A::value_type; 11 | static constexpr X act(const X& x, const A& a, int) { 12 | return Max(-inf, x + a); 13 | } 14 | }; -------------------------------------------------------------------------------- /acted_monoid/max_assign.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/max.hpp" 3 | #include "monoid/assign.hpp" 4 | 5 | template > 6 | struct ActedMonoid_Max_Assign { 7 | using Monoid_X = Monoid_Max; 8 | using Monoid_A = Monoid_Assign; 9 | using X = Monoid_X::value_type; 10 | using A = Monoid_A::value_type; 11 | static constexpr X act(const X& x, const A& a, int) { 12 | return a == none ? x : a; 13 | } 14 | }; -------------------------------------------------------------------------------- /acted_monoid/max_max.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/max.hpp" 3 | 4 | template 5 | struct ActedMonoid_Max_Max { 6 | using Monoid_X = Monoid_Max; 7 | using Monoid_A = Monoid_Max; 8 | using X = Monoid_X::value_type; 9 | using A = Monoid_A::value_type; 10 | static constexpr X act(const X& x, const A& a, int) { 11 | return Max(x, a); 12 | } 13 | }; -------------------------------------------------------------------------------- /acted_monoid/max_min.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/max.hpp" 3 | #include "monoid/min.hpp" 4 | 5 | template 6 | struct ActedMonoid_Max_Min { 7 | using Monoid_X = Monoid_Max; 8 | using Monoid_A = Monoid_Min; 9 | using X = Monoid_X::value_type; 10 | using A = Monoid_A::value_type; 11 | static constexpr X act(const X& x, const A& a, int) { 12 | return Min(x, a); 13 | } 14 | }; -------------------------------------------------------------------------------- /acted_monoid/maxmaxcnt2_add.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/maxmaxcnt2.hpp" 3 | #include "monoid/add.hpp" 4 | 5 | template 6 | struct ActedMonoid_MinMincnt2_Add { 7 | using Monoid_X = Monoid_MaxMaxcnt2; 8 | using Monoid_A = Monoid_Add; 9 | using X = Monoid_X::value_type; 10 | using A = Monoid_A::value_type; 11 | static constexpr X act(const X& x, const A& a, int) { 12 | return {Max(-inf, x.max + a), Max(-inf, x.max2 + a), x.cnt, x.cnt2}; 13 | } 14 | }; -------------------------------------------------------------------------------- /acted_monoid/maxmaxcnt_add.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/maxmaxcnt.hpp" 3 | #include "monoid/add.hpp" 4 | 5 | template 6 | struct ActedMonoid_MaxMaxcnt_Add { 7 | using Monoid_X = Monoid_MaxMaxcnt; 8 | using Monoid_A = Monoid_Add; 9 | using X = Monoid_X::value_type; 10 | using A = Monoid_A::value_type; 11 | static constexpr X act(const X& x, const A& a, int) { 12 | return {Max(-inf, x.first + a), x.second}; 13 | } 14 | }; -------------------------------------------------------------------------------- /acted_monoid/min2_add.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/min2.hpp" 3 | #include "monoid/add.hpp" 4 | 5 | template 6 | struct ActedMonoid_Min2_Add { 7 | using Monoid_X = Monoid_Min2; 8 | using Monoid_A = Monoid_Add; 9 | using X = Monoid_X::value_type; 10 | using A = Monoid_A::value_type; 11 | static constexpr X act(const X& x, const A& a, int) { 12 | return {Min(inf, x.first + a), Min(inf, x.second + a)}; 13 | } 14 | }; -------------------------------------------------------------------------------- /acted_monoid/min_add.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/min.hpp" 3 | #include "monoid/add.hpp" 4 | 5 | template 6 | struct ActedMonoid_Min_Add { 7 | using Monoid_X = Monoid_Min; 8 | using Monoid_A = Monoid_Add; 9 | using X = Monoid_X::value_type; 10 | using A = Monoid_A::value_type; 11 | static constexpr X act(const X& x, const A& a, int) { 12 | return Min(inf, x + a); 13 | } 14 | }; -------------------------------------------------------------------------------- /acted_monoid/min_assign.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/min.hpp" 3 | #include "monoid/assign.hpp" 4 | 5 | template > 6 | struct ActedMonoid_Min_Assign { 7 | using Monoid_X = Monoid_Min; 8 | using Monoid_A = Monoid_Assign; 9 | using X = Monoid_X::value_type; 10 | using A = Monoid_A::value_type; 11 | static constexpr X act(const X& x, const A& a, int) { 12 | return a == none ? x : a; 13 | } 14 | }; -------------------------------------------------------------------------------- /acted_monoid/min_max.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/min.hpp" 3 | #include "monoid/max.hpp" 4 | 5 | template 6 | struct ActedMonoid_Min_Max { 7 | using Monoid_X = Monoid_Min; 8 | using Monoid_A = Monoid_Max; 9 | using X = Monoid_X::value_type; 10 | using A = Monoid_A::value_type; 11 | static constexpr X act(const X& x, const A& a, int) { 12 | return Max(x, a); 13 | } 14 | }; -------------------------------------------------------------------------------- /acted_monoid/min_min.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/min.hpp" 3 | 4 | template 5 | struct ActedMonoid_Min_Min { 6 | using Monoid_X = Monoid_Min; 7 | using Monoid_A = Monoid_Min; 8 | using X = Monoid_X::value_type; 9 | using A = Monoid_A::value_type; 10 | static constexpr X act(const X& x, const A& a, int) { 11 | return Min(x, a); 12 | } 13 | }; -------------------------------------------------------------------------------- /acted_monoid/minmax_add.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "acted_monoid/min_add.hpp" 3 | #include "acted_monoid/max_add.hpp" 4 | #include "acted_monoid/acted_monoid_combine.hpp" 5 | 6 | template 7 | using ActedMonoid_MinMax_Add = ActedMonoid_Combine, ActedMonoid_Max_Add>; -------------------------------------------------------------------------------- /acted_monoid/minmax_assign.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "acted_monoid/min_assign.hpp" 3 | #include "acted_monoid/max_assign.hpp" 4 | #include "acted_monoid/acted_monoid_combine.hpp" 5 | 6 | template 7 | using ActedMonoid_MinMax_Assign = ActedMonoid_Combine, ActedMonoid_Max_Assign>; -------------------------------------------------------------------------------- /acted_monoid/minmax_mul.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/minmax.hpp" 3 | #include "monoid/mul.hpp" 4 | 5 | template 6 | struct ActedMonoid_MinMax_Mul { 7 | using Monoid_X = Monoid_MinMax; 8 | using Monoid_A = Monoid_Mul; 9 | using X = Monoid_X::value_type; 10 | using A = Monoid_A::value_type; 11 | static constexpr X act(const X& x, const A& a, int) { 12 | if (a == 0) 13 | return {}; 14 | auto&& [mn, mx] = x; 15 | if (a > 0) 16 | return {mn * a, mx * a}; 17 | return {mx * a, mn * a}; 18 | } 19 | }; -------------------------------------------------------------------------------- /acted_monoid/minmincnt2_add.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/minmincnt2.hpp" 3 | #include "monoid/add.hpp" 4 | 5 | template 6 | struct ActedMonoid_MinMincnt2_Add { 7 | using Monoid_X = Monoid_MinMincnt2; 8 | using Monoid_A = Monoid_Add; 9 | using X = Monoid_X::value_type; 10 | using A = Monoid_A::value_type; 11 | static constexpr X act(const X& x, const A& a, int) { 12 | return {Min(inf, x.min + a), Min(inf, x.min2 + a), x.cnt, x.cnt2}; 13 | } 14 | }; -------------------------------------------------------------------------------- /acted_monoid/minmincnt_add.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/minmincnt.hpp" 3 | #include "monoid/add.hpp" 4 | 5 | template 6 | struct ActedMonoid_MinMincnt_Add { 7 | using Monoid_X = Monoid_MinMincnt; 8 | using Monoid_A = Monoid_Add; 9 | using X = Monoid_X::value_type; 10 | using A = Monoid_A::value_type; 11 | static constexpr X act(const X& x, const A& a, int) { 12 | return {Min(inf, x.first + a), x.second}; 13 | } 14 | }; -------------------------------------------------------------------------------- /acted_monoid/rollinghash_add.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/rollinghash.hpp" 3 | #include "monoid/add.hpp" 4 | 5 | template 6 | struct ActedMonoid_Rollinghash_Add { 7 | using Monoid_X = Monoid_Rollinghash; 8 | using Monoid_A = Monoid_Add; 9 | using X = Monoid_X::value_type; 10 | using A = Monoid_A::value_type; 11 | 12 | static inline const mint invbase = (Monoid_X::base - 1).inv(); 13 | static constexpr X act(const X& x, const A& a, int sz) { 14 | return {x.first, x.second + a * (x.first - 1) * invbase}; 15 | } 16 | }; -------------------------------------------------------------------------------- /acted_monoid/sum_add.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/add.hpp" 3 | 4 | template 5 | struct ActedMonoid_Sum_Add { 6 | using Monoid_X = Monoid_Add; 7 | using Monoid_A = Monoid_Add; 8 | using X = Monoid_X::value_type; 9 | using A = Monoid_A::value_type; 10 | static constexpr X act(const X& x, const A& a, int sz) { 11 | return x + a * sz; 12 | } 13 | }; -------------------------------------------------------------------------------- /acted_monoid/sum_affine.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/add.hpp" 3 | #include "monoid/affine.hpp" 4 | 5 | template 6 | struct ActedMonoid_Sum_Affine { 7 | using Monoid_X = Monoid_Add; 8 | using Monoid_A = Monoid_Affine; 9 | using X = Monoid_X::value_type; 10 | using A = Monoid_A::value_type; 11 | static constexpr X act(const X& x, const A& a, int sz) { 12 | return x * a.first + sz * a.second; 13 | } 14 | }; -------------------------------------------------------------------------------- /acted_monoid/sum_assign.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/add.hpp" 3 | #include "monoid/assign.hpp" 4 | 5 | template > 6 | struct ActedMonoid_Sum_Assign { 7 | using Monoid_X = Monoid_Add; 8 | using Monoid_A = Monoid_Assign; 9 | using X = Monoid_X::value_type; 10 | using A = Monoid_A::value_type; 11 | static constexpr X act(const X& x, const A& a, int sz) { 12 | return a == none ? x : a * sz; 13 | } 14 | }; -------------------------------------------------------------------------------- /acted_monoid/sum_mul.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/add.hpp" 3 | #include "monoid/mul.hpp" 4 | 5 | template 6 | struct ActedMonoid_Sum_Mul { 7 | using Monoid_X = Monoid_Add; 8 | using Monoid_A = Monoid_Mul; 9 | using X = Monoid_X::value_type; 10 | using A = Monoid_A::value_type; 11 | static constexpr X act(const X& x, const A& a, int) { 12 | return x * a; 13 | } 14 | }; -------------------------------------------------------------------------------- /acted_monoid/summax_add.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "acted_monoid/sum_add.hpp" 3 | #include "acted_monoid/max_add.hpp" 4 | #include "acted_monoid/acted_monoid_combine.hpp" 5 | 6 | template 7 | using ActedMonoid_SumMax_Add = ActedMonoid_Combine, ActedMonoid_Max_Add>; -------------------------------------------------------------------------------- /acted_monoid/summax_assign.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "acted_monoid/sum_assign.hpp" 3 | #include "acted_monoid/max_assign.hpp" 4 | #include "acted_monoid/acted_monoid_combine.hpp" 5 | 6 | template 7 | using ActedMonoid_SumMax_Assign = ActedMonoid_Combine, ActedMonoid_Max_Assign>; -------------------------------------------------------------------------------- /acted_monoid/summin_add.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "acted_monoid/sum_add.hpp" 3 | #include "acted_monoid/min_add.hpp" 4 | #include "acted_monoid/acted_monoid_combine.hpp" 5 | 6 | template 7 | using ActedMonoid_SumMin_Add = ActedMonoid_Combine, ActedMonoid_Min_Add>; -------------------------------------------------------------------------------- /acted_monoid/summin_assign.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "acted_monoid/sum_assign.hpp" 3 | #include "acted_monoid/min_assign.hpp" 4 | #include "acted_monoid/acted_monoid_combine.hpp" 5 | 6 | template 7 | using ActedMonoid_SumMin_Assign = ActedMonoid_Combine, ActedMonoid_Min_Assign>; -------------------------------------------------------------------------------- /acted_monoid/summinmax_add.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "acted_monoid/sum_add.hpp" 3 | #include "acted_monoid/min_add.hpp" 4 | #include "acted_monoid/max_add.hpp" 5 | #include "acted_monoid/acted_monoid_combine.hpp" 6 | 7 | template 8 | using ActedMonoid_SumMinMax_Add = ActedMonoid_Combine, ActedMonoid_Min_Add, ActedMonoid_Max_Add>; -------------------------------------------------------------------------------- /acted_monoid/summinmax_assign.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "acted_monoid/sum_assign.hpp" 3 | #include "acted_monoid/min_assign.hpp" 4 | #include "acted_monoid/max_assign.hpp" 5 | #include "acted_monoid/acted_monoid_combine.hpp" 6 | 7 | template 8 | using ActedMonoid_SumMinMax_Assign = ActedMonoid_Combine, ActedMonoid_Min_Assign, ActedMonoid_Max_Assign>; -------------------------------------------------------------------------------- /acted_monoid/summinmax_mul.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "acted_monoid/sum_mul.hpp" 3 | #include "acted_monoid/minmax_mul.hpp" 4 | #include "acted_monoid/acted_monoid_combine.hpp" 5 | 6 | template 7 | using ActedMonoid_SumMinMax_Mul = ActedMonoid_Combine, ActedMonoid_MinMax_Mul>; -------------------------------------------------------------------------------- /acted_set/from_monoid.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct ActedSet_From_Monoid { 5 | using Monoid_A = Monoid; 6 | using A = Monoid::value_type; 7 | using S = A; 8 | static constexpr S act(const S& x, const A& a) { return Monoid::op(x, a); } 9 | }; -------------------------------------------------------------------------------- /all.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #if defined(LX_LOCAL) 3 | #include 4 | #endif 5 | #include "io/io.hpp" -------------------------------------------------------------------------------- /all2.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #if defined(LX_LOCAL) 3 | #include 4 | #endif 5 | #include "io/io2.hpp" -------------------------------------------------------------------------------- /cpp11/all.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "timer.hpp" 3 | #include "template.hpp" 4 | #include "io.hpp" 5 | -------------------------------------------------------------------------------- /cpp11/bit.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct BIT { 6 | const int n; 7 | vc a; 8 | BIT(int n): n(n), a(n) {} 9 | void add(int x, T v) { 10 | for (int i = x + 1; i <= n; i += i & -i) 11 | a[i - 1] += v; 12 | } 13 | T sum(int x) { 14 | T ans = 0; 15 | for (int i = x + 1; i > 0; i -= i & -i) 16 | ans += a[i - 1]; 17 | return ans; 18 | } 19 | T sum(int l, int r) { 20 | return sum(r - 1) - sum(l - 1); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /cpp11/bsearch.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | template 5 | U bsearch(T&& check, U ok, V ng) { 6 | while (std::abs(ok - ng) > 1) { 7 | auto x = (ng + ok) >> 1; 8 | if (check(x)) 9 | ok = x; 10 | else 11 | ng = x; 12 | } 13 | return ok; 14 | } -------------------------------------------------------------------------------- /cpp11/compatibility.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "types.hpp" 3 | 4 | #define FOR _for 5 | #define FORIN foreach 6 | using ll = i64; 7 | #define INT(...) dR(int, __VA_ARGS__) 8 | #define LL(...) dR(ll, __VA_ARGS__) 9 | #define STR(...) dR(std::string, __VA_ARGS__) 10 | #define CHR(...) dR(char, __VA_ARGS__) 11 | #define DBL(...) dR(ld, __VA_ARGS__) -------------------------------------------------------------------------------- /cpp11/dsu.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | struct DSU { 5 | vi f, siz; 6 | int comp; 7 | DSU(int n): f(n), siz(n, 1), comp(n) { std::iota(all(f), 0); } 8 | int leader(int x) { 9 | while (x != f[x]) 10 | x = f[x] = f[f[x]]; 11 | return x; 12 | } 13 | bool same(int x, int y) { 14 | return leader(x) == leader(y); 15 | } 16 | bool merge(int x, int y) { 17 | x = leader(x); 18 | y = leader(y); 19 | if (x == y) 20 | return false; 21 | comp--; 22 | if (siz[x] < siz[y]) 23 | std::swap(x, y); 24 | siz[x] += siz[y]; 25 | siz[y] = 0; 26 | f[y] = x; 27 | return true; 28 | } 29 | int size(int x) { 30 | return siz[leader(x)]; 31 | } 32 | }; -------------------------------------------------------------------------------- /cpp11/isqrt.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | i64 isqrt(i64 n) { 5 | if (n <= 0) 6 | return 0; 7 | i64 x = sqrt(n); 8 | while ((x + 1) * (x + 1) <= n) 9 | x++; 10 | while (x * x > n) 11 | x--; 12 | return x; 13 | } -------------------------------------------------------------------------------- /cpp11/rng.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | std::mt19937 rnd(std::random_device{}()); 5 | std::mt19937_64 rnd64(std::random_device{}()); 6 | -------------------------------------------------------------------------------- /cpp11/timer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | #ifdef LX_LOCAL 5 | namespace { 6 | struct Timer { 7 | clock_t begin; 8 | Timer(): begin(clock()) {} 9 | ~Timer() { 10 | double t = (clock() - begin) * 1000. / CLOCKS_PER_SEC; 11 | fprintf(stderr, "\033[1;32m"); 12 | if (t >= 60000) 13 | fprintf(stderr, "%.2lfmin\n", t / 60000.); 14 | else if (t >= 1000) 15 | fprintf(stderr, "%.2lfs\n", t / 1000.); 16 | else 17 | fprintf(stderr, "%.0lfms\n", t); 18 | fprintf(stderr, "\033[0m"); 19 | } 20 | } _; 21 | } // namespace 22 | #endif -------------------------------------------------------------------------------- /ds/bit.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct BIT { 6 | int n; 7 | vc a; 8 | BIT(int n): n(n), a(n) {} 9 | void add(int x, T v) { 10 | for (int i = x + 1; i <= n; i += i & -i) 11 | a[i - 1] += v; 12 | } 13 | T sum(int x) { 14 | T ans = 0; 15 | for (int i = x + 1; i > 0; i -= i & -i) 16 | ans += a[i - 1]; 17 | return ans; 18 | } 19 | T sum(int l, int r) { 20 | return sum(r - 1) - sum(l - 1); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /ds/bit_vector.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | struct Bit_Vector { 5 | vc> a; 6 | Bit_Vector(int n): a((n + 63) >> 5) {} 7 | void set(int i) { a[i >> 5].first |= 1U << (i & 31); } 8 | void reset(int i) { a[i >> 5].first &= ~(1U << (i & 31)); } 9 | void build() { 10 | _for (i, len(a) - 1) 11 | a[i + 1].second = a[i].second + std::popcount(a[i].first); 12 | } 13 | u32 rank1(int i) const { 14 | auto [x, y] = a[i >> 5]; 15 | return y + std::popcount(x & ((1U << (i & 31)) - 1)); 16 | } 17 | u32 rank1(int l, int r) const { return rank1(r) - rank1(l); } 18 | u32 rank0(int i) const { return i - rank1(i); } 19 | u32 rank0(int l, int r) const { return rank0(r) - rank0(l); } 20 | u32 rank(int i, bool b) const { return b ? rank1(i) : rank0(i); } 21 | u32 rank(int l, int r, bool b) const { return b ? rank1(l, r) : rank0(l, r); } 22 | }; -------------------------------------------------------------------------------- /ds/dynamic_unionfind.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ds/dynamic_array.hpp" 3 | 4 | template 5 | struct Dynamic_UnionFind { 6 | Dynamic_Array a; 7 | using np = decltype(a)::np; 8 | Dynamic_UnionFind(): a(-1) {} 9 | np new_node() { return a.new_node(); } 10 | int get(np u, int x) { 11 | loop { 12 | int p = a.get(u, x); 13 | if (p < 0) 14 | return x; 15 | x = p; 16 | } 17 | } 18 | bool same(np u, int x, int y) { return get(u, x) == get(u, y); } 19 | std::pair merge(np u, int x, int y) { 20 | x = get(u, x), y = get(u, y); 21 | if (x == y) 22 | return {u, false}; 23 | if (a.get(u, x) > a.get(u, y)) 24 | swap(x, y); 25 | int sz = a.get(u, x) + a.get(u, y); 26 | u = a.set(u, x, sz); 27 | u = a.set(u, y, x); 28 | return {u, true}; 29 | } 30 | }; -------------------------------------------------------------------------------- /ds/removable_queue.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct RemovableQueue: private Q { 6 | using T = Q::value_type; 7 | Q rq; 8 | int size() const { return Q::size() - len(rq); } 9 | bool empty() const { return !size(); } 10 | 11 | RemovableQueue() = default; 12 | RemovableQueue(const vc& a): Q(all(a)) {} 13 | T pop() { 14 | T top = this->top(); 15 | Q::pop(); 16 | return top; 17 | } 18 | T top() { 19 | refresh(); 20 | return Q::top(); 21 | } 22 | void push(T x) { Q::push(std::move(x)); } 23 | void emplace(auto&&... args) { Q::emplace(FORWARD(args)...); } 24 | void remove(T x) { rq.push(std::move(x)); } 25 | 26 | private: 27 | void refresh() { 28 | while (!rq.empty() && rq.top() == Q::top()) { 29 | rq.pop(); 30 | Q::pop(); 31 | } 32 | } 33 | }; -------------------------------------------------------------------------------- /ds/rollback_array.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct Rollback_Array { 6 | vc a; 7 | vc> his; 8 | int n; 9 | Rollback_Array() = default; 10 | Rollback_Array(int n, T x = {}): a(n, x), n(n) {} 11 | Rollback_Array(const vc& a): a(a), n(len(a)) {} 12 | int time() const { return len(his); } 13 | void rollback(int t) { 14 | _for_r (i, t, time()) { 15 | auto [x, y] = pop(his); 16 | a[x] = y; 17 | } 18 | } 19 | void set(int x, T y) { 20 | his.eb(x, a[x]); 21 | a[x] = y; 22 | } 23 | const T& get(int x) const { return a[x]; } 24 | const T& operator[](int x) const { return get(x); } 25 | }; -------------------------------------------------------------------------------- /ds/rollback_unionfind.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ds/rollback_array.hpp" 3 | 4 | template 5 | struct Rollback_UnionFind { 6 | Rollback_Array a; 7 | Rollback_UnionFind(int n): a(n, -1) {} 8 | int get(int x) const { 9 | while (a[x] >= 0) 10 | x = a[x]; 11 | return x; 12 | } 13 | int operator[](int x) const { return get(x); } 14 | bool same(int x, int y) const { return get(x) == get(y); } 15 | bool merge(int x, int y) { 16 | x = get(x), y = get(y); 17 | if (x == y) 18 | return false; 19 | if (ByRank && a[x] > a[y]) 20 | swap(x, y); 21 | a.set(x, a[x] + a[y]); 22 | a.set(y, x); 23 | return true; 24 | } 25 | int size(int x) const { return -a[get(x)]; } 26 | int time() const { return a.time(); } 27 | void rollback(int t) { a.rollback(t); } 28 | }; -------------------------------------------------------------------------------- /ds/segtree_beats.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ds/lazy_segtree.hpp" 3 | 4 | template 5 | using SegTree_Beats = Lazy_SegTree_Base; -------------------------------------------------------------------------------- /ds/sqrtfenwicktree_01.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ds/sqrtfenwicktree.hpp" 3 | #include "ds/fenwicktree_01.hpp" 4 | 5 | using SqrtFenwickTree_01 = FenwickTree_01Base; -------------------------------------------------------------------------------- /ds/unionfind.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct UnionFind { 6 | int n, comp; 7 | vi a; 8 | UnionFind(int n = 0) { build(n); } 9 | void build(int n) { 10 | this->n = comp = n; 11 | a.assign(n, -1); 12 | } 13 | int get(int x) { 14 | while (a[x] >= 0) { 15 | int y = a[a[x]]; 16 | if (y < 0) 17 | return a[x]; 18 | x = a[x] = y; 19 | } 20 | return x; 21 | } 22 | int operator[](int x) { return get(x); } 23 | bool same(int x, int y) { return get(x) == get(y); } 24 | bool merge(int x, int y) { 25 | x = get(x), y = get(y); 26 | if (x == y) 27 | return false; 28 | comp--; 29 | if (ByRank && a[x] > a[y]) 30 | swap(x, y); 31 | a[x] += a[y]; 32 | a[y] = x; 33 | return true; 34 | } 35 | int size(int x) { return -a[get(x)]; } 36 | vi get_all() { 37 | vi ans(n); 38 | _for (i, n) 39 | ans[i] = get(i); 40 | return ans; 41 | } 42 | }; -------------------------------------------------------------------------------- /ds/unit_prod.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct Unit_Prod { 6 | constexpr auto operator()(i64, i64) const { return Monoid::unit(); } 7 | }; -------------------------------------------------------------------------------- /ds2d/cumsum2d.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct Cumsum2D { 6 | int n, m; 7 | vvc s; 8 | Cumsum2D(int n, int m): n(n), m(m), s(n + 1, vc(m + 1)) {} 9 | Cumsum2D(const vvc& a) { 10 | n = len(a), m = len(a[0]); 11 | s.assign(n + 1, vc(m + 1)); 12 | _for (i, n) 13 | _for (j, m) 14 | s[i + 1][j + 1] = a[i][j]; 15 | build(); 16 | } 17 | void build() { 18 | _for (i, n + 1) 19 | _for (j, m) 20 | s[i][j + 1] += s[i][j]; 21 | _for (i, n) 22 | _for (j, m + 1) 23 | s[i + 1][j] += s[i][j]; 24 | } 25 | auto sum(int x1, int y1, int x2, int y2) { return s[x1][y1] - s[x1][y2] - s[x2][y1] + s[x2][y2]; } 26 | }; -------------------------------------------------------------------------------- /enumerate/combinations.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | void enumerate_combinations(auto&& a, int r, auto&& f) { 5 | using T = range_value_t; 6 | int n = len(a); 7 | if (r > n) 8 | return; 9 | vi I(r); 10 | iota(all(I), 0); 11 | vc b(r); 12 | _for (i, r) 13 | b[i] = a[I[i]]; 14 | f(b); 15 | loop { 16 | int i = r - 1; 17 | while (i >= 0 && I[i] == i + n - r) 18 | i--; 19 | if (i < 0) 20 | return; 21 | I[i]++; 22 | _for (j, i + 1, r) 23 | I[j] = I[j - 1] + 1; 24 | _for (i, r) 25 | b[i] = a[I[i]]; 26 | f(b); 27 | } 28 | } -------------------------------------------------------------------------------- /enumerate/permutations.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | void enumerate_permutations(auto&& a, int r, auto&& f) { 5 | using T = range_value_t; 6 | int n = len(a); 7 | if (r > n) 8 | return; 9 | vi I(n); 10 | iota(all(I), 0); 11 | vi C(r); 12 | _for (i, r) 13 | C[i] = n - i; 14 | vc b(r); 15 | _for (i, r) 16 | b[i] = a[I[i]]; 17 | f(b); 18 | loop { 19 | bool done = true; 20 | _for_r (i, r) { 21 | if (!--C[i]) { 22 | rotate(I.begin() + i, I.begin() + i + 1, I.end()); 23 | C[i] = n - i; 24 | } 25 | else { 26 | int j = C[i]; 27 | swap(I[i], I[n - j]); 28 | _for (i, r) 29 | b[i] = a[I[i]]; 30 | f(b); 31 | done = false; 32 | break; 33 | } 34 | } 35 | if (done) 36 | return; 37 | } 38 | } -------------------------------------------------------------------------------- /enumerate/xor_range.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | // Enumerates intervals [l, r) of x such that L <= (x ^ a) < R. 5 | void xor_range(u64 a, u64 l, u64 r, auto&& f) { 6 | _for (i, 64) { 7 | if (l == r) 8 | break; 9 | u64 t = 1ULL << i; 10 | if (l & t) { 11 | f(l ^ a, (l ^ a) + t); 12 | l += t; 13 | } 14 | if (r & t) { 15 | f((r - t) ^ a, ((r - t) ^ a) + t); 16 | r -= t; 17 | } 18 | if (a & t) 19 | a ^= t; 20 | } 21 | } -------------------------------------------------------------------------------- /graph/auxiliary_tree.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/tree.hpp" 3 | 4 | template 5 | auto auxiliary_tree(const TREE& tree, vc V) { 6 | sort(V, [&](int x, int y) { return tree.lid[x] < tree.lid[y]; }); 7 | int n = len(V); 8 | _for (i, n - 1) 9 | V.eb(tree.lca(V[i], V[i + 1])); 10 | V.eb(tree.lca(V[n - 1], V[0])); 11 | V.eb(tree.id[0]); 12 | sort(V, [&](int x, int y) { return tree.lid[x] < tree.lid[y]; }); 13 | V.erase(std::unique(all(V)), V.end()); 14 | n = len(V); 15 | Graph g(n); 16 | vi st{0}; 17 | _for (i, 1, n) { 18 | loop { 19 | int p = V[st.back()]; 20 | if (tree.in_subtree(V[i], p)) 21 | break; 22 | st.pop_back(); 23 | } 24 | int p = V[st.back()], u = V[i]; 25 | if constexpr (TREE::graph_type::is_weighted()) 26 | g.add(st.back(), i, tree.wdep[u] - tree.wdep[p]); 27 | else 28 | g.add(st.back(), i, tree.dep[u] - tree.dep[p]); 29 | st.eb(i); 30 | } 31 | g.build(); 32 | return std::pair{std::move(g), std::move(V)}; 33 | } -------------------------------------------------------------------------------- /graph/bellmanford.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/base.hpp" 3 | 4 | template 5 | struct BellmanFordResult { 6 | vc dis; 7 | vi par; 8 | }; 9 | template 10 | auto BellmanFord(const auto& g, int s = 0) { 11 | const int n = g.n; 12 | vc dis(n, inf); 13 | vi par(n, -1); 14 | dis[s] = 0; 15 | int cnt = 0; 16 | loop { 17 | cnt++; 18 | bool upd = false; 19 | _for (u, n) 20 | if (dis[u] != inf) 21 | foreach (v, g[u]) { 22 | T t = dis[u] + v.cost; 23 | if (dis[u] == -inf) 24 | t = -inf; 25 | chkmax(t, -inf); 26 | if (t < dis[v]) { 27 | if (cnt >= n) 28 | t = -inf; 29 | dis[v] = t; 30 | par[v] = u; 31 | upd = true; 32 | } 33 | } 34 | if (!upd) 35 | break; 36 | } 37 | return BellmanFordResult{std::move(dis), std::move(par)}; 38 | } -------------------------------------------------------------------------------- /graph/bipartite_vertex_coloring.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/base.hpp" 3 | #include "ds/unionfind.hpp" 4 | 5 | std::optional bipartite_vertex_coloring(const UndirectedGraph auto& g) { 6 | const int n = g.n; 7 | UnionFind uf(n * 2); 8 | foreach (e, g.edges) { 9 | int u = e.from, v = e.to; 10 | uf.merge(u + n, v); 11 | uf.merge(u, v + n); 12 | } 13 | vi col(n * 2, -1); 14 | _for (i, n) 15 | if (uf[i] == i && col[uf[i]] < 0) { 16 | col[uf[i]] = 0; 17 | col[uf[i + n]] = 1; 18 | } 19 | _for (i, n) 20 | col[i] = col[uf[i]]; 21 | col.resize(n); 22 | _for (i, n) 23 | if (uf[i] == uf[i + n]) 24 | return std::nullopt; 25 | return col; 26 | } -------------------------------------------------------------------------------- /graph/dual_tree_monoid.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/tree_monoid_base.hpp" 3 | #include "ds/dual_segtree.hpp" 4 | 5 | template 6 | using Dual_Tree_Monoid = Tree_Monoid_Base; -------------------------------------------------------------------------------- /graph/fast_lca.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ds/sparse_table.hpp" 3 | #include "monoid/min.hpp" 4 | #include "graph/tree.hpp" 5 | 6 | template 7 | struct Fast_Lca_Tree: Tree { 8 | Sparse_Table> st; 9 | vi pos; 10 | using Tree::n; 11 | Fast_Lca_Tree(G& g, int root = 0): Tree(g, root), pos(n) { 12 | vi a(n * 2); 13 | _for (i, n) { 14 | int x = this->elid(i), y = this->erid(i); 15 | pos[i] = x; 16 | a[x] = this->lid[i]; 17 | a[y] = this->lid[this->fa[i]]; 18 | } 19 | a.back() = -1; 20 | st.build(a); 21 | } 22 | int lca(int u, int v) const { 23 | u = pos[u], v = pos[v]; 24 | if (u > v) 25 | swap(u, v); 26 | return this->id[st.prod(u, v + 1)]; 27 | } 28 | int lca(int u, int v, int r) const { return lca(u, v) ^ lca(u, r) ^ lca(v, r); } 29 | int dist(int u, int v) const { return this->dep[u] + this->dep[v] - this->dep[lca(u, v)] * 2; } 30 | auto wdist(int u, int v) const requires (G::is_weighted()) 31 | { return this->wdep[u] + this->wdep[v] - this->wdep[lca(u, v)] * 2; } 32 | }; -------------------------------------------------------------------------------- /graph/find_centroids.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/base.hpp" 3 | 4 | pi find_centroids(const auto& g) { 5 | const int n = g.n; 6 | vi par(n, -1), V(n), sz(n); 7 | int l = 0, r = 0; 8 | V[r++] = 0; 9 | while (l < r) { 10 | int u = V[l++]; 11 | foreach (v, g[u]) 12 | if (v != par[u]) { 13 | V[r++] = v; 14 | par[v] = u; 15 | } 16 | } 17 | _for_r (i, n) { 18 | int u = V[i], p = par[u]; 19 | sz[u]++; 20 | if (p != -1) 21 | sz[p] += sz[u]; 22 | } 23 | int m = n / 2; 24 | pi ans{-1, -1}; 25 | _for (u, n) { 26 | if (BLK { 27 | if (n - sz[u] > m) 28 | return false; 29 | foreach (v, g[u]) 30 | if (v != par[u] && sz[v] > m) 31 | return false; 32 | return true; 33 | }) { 34 | if (ans.first == -1) 35 | ans.first = u; 36 | else 37 | ans.second = u; 38 | } 39 | } 40 | return ans; 41 | } -------------------------------------------------------------------------------- /graph/floyd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/base.hpp" 3 | 4 | template 5 | auto floyd(const auto& g) { 6 | const int n = g.n; 7 | VECI(dis, n, n, inf); 8 | _for (i, n) 9 | dis[i][i] = 0; 10 | _for (u, n) 11 | foreach (v, g[u]) 12 | chkmin(dis[u][v], v.cost); 13 | _for (k, n) 14 | _for (i, n) 15 | if (dis[i][k] != inf) 16 | _for (j, n) 17 | if (dis[k][j] != inf) 18 | chkmin(dis[i][j], dis[i][k] + dis[k][j]); 19 | return dis; 20 | } -------------------------------------------------------------------------------- /graph/grid_bfs.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | enum class Connectivity : u8 { 5 | Four = 4, 6 | Eight = 8, 7 | }; 8 | 9 | template 10 | vvi grid_bfs(const vc& g, const vc& s, V wall, Connectivity conn = Connectivity::Four) { 11 | const int n = len(g), m = len(g[0]); 12 | VECI(dis, n, m, inf); 13 | std::deque q; 14 | foreach (sx, sy, s) { 15 | dis[sx][sy] = 0; 16 | q.eb(sx, sy); 17 | } 18 | constexpr int dx[]{0, 0, -1, 1, -1, -1, 1, 1}; 19 | constexpr int dy[]{-1, 1, 0, 0, -1, 1, -1, 1}; 20 | while (!q.empty()) { 21 | auto [x, y] = pop(q); 22 | _for (i, int(conn)) { 23 | int nx = x + dx[i], ny = y + dy[i]; 24 | if (nx < 0 || nx >= n || ny < 0 || ny >= m || count(wall, g[nx][ny]) || dis[nx][ny] != inf) 25 | continue; 26 | dis[nx][ny] = dis[x][y] + 1; 27 | q.eb(nx, ny); 28 | } 29 | } 30 | return dis; 31 | } 32 | template 33 | vvi grid_bfs(const vc& g, int sx, int sy, V wall, Connectivity conn = Connectivity::Four) { return grid_bfs(g, {{sx, sy}}, wall, conn); } -------------------------------------------------------------------------------- /graph/hash_tree.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "random/hash.hpp" 3 | 4 | u64 hash_tree(const auto& g, int r = 0) { 5 | auto dfs = [&](auto&& dfs, int u, int f) -> u64 { 6 | u64 h = 1; 7 | foreach (v, g[u]) 8 | if (v != f) 9 | h += hash(dfs(dfs, v, u)); 10 | return h; 11 | }; 12 | return dfs(dfs, r, -1); 13 | } -------------------------------------------------------------------------------- /graph/kruskal.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/base.hpp" 3 | #include "ds/unionfind.hpp" 4 | 5 | template 6 | struct KruskalResult { 7 | T cost; 8 | vcb in; 9 | G mst; 10 | }; 11 | template 12 | auto kruskal(const auto& g) { 13 | const int n = g.n, m = g.m; 14 | vi I(m); 15 | iota(all(I), 0); 16 | sort(I, [&](int i, int j) { return g.edges[i].cost < g.edges[j].cost; }); 17 | UnionFind uf(n); 18 | T cost{}; 19 | vcb in(m); 20 | std::decay_t mst(n, n - 1); 21 | foreach (i, I) 22 | if (auto&& e = g.edges[i]; uf.merge(e.from, e.to)) { 23 | in[i] = 1; 24 | mst.add(e.from, e.to, e.cost); 25 | cost += e.cost; 26 | } 27 | mst.build(); 28 | return KruskalResult{cost, std::move(in), std::move(mst)}; 29 | } -------------------------------------------------------------------------------- /graph/lazy_tree_monoid.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/tree_monoid_base.hpp" 3 | #include "ds/lazy_segtree.hpp" 4 | 5 | template 6 | using Lazy_Tree_Monoid = Tree_Monoid_Base; -------------------------------------------------------------------------------- /graph/negative_cycle.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/bellmanford.hpp" 3 | 4 | template 5 | bool negative_cycle(const auto& g) { 6 | auto [dis, par] = BellmanFord(g); 7 | return min(dis) == -inf; 8 | } -------------------------------------------------------------------------------- /graph/reachability_bitset.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ds/bitset.hpp" 3 | 4 | vc reachability_bitset(vc g) { 5 | const int n = len(g); 6 | _for (i, n) 7 | g[i][i] = true; 8 | _for (k, n) 9 | _for (i, n) 10 | if (g[i][k]) 11 | g[i] |= g[k]; 12 | return g; 13 | } -------------------------------------------------------------------------------- /graph/restore_path.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | vi restore_path(vi par, int t) { 5 | vi r{t}; 6 | while (par[r.back()] != -1) 7 | r.eb(par[r.back()]); 8 | reverse(r); 9 | return r; 10 | } -------------------------------------------------------------------------------- /graph/static_tree_monoid.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/tree_monoid_base.hpp" 3 | #include "ds/disjoint_sparse_table.hpp" 4 | 5 | template 6 | using Static_Tree_Monoid = Tree_Monoid_Base; -------------------------------------------------------------------------------- /graph/topological_sort.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/base.hpp" 3 | 4 | std::optional toposort(const DirectedGraph auto& g) { 5 | const int n = g.n; 6 | vcb vis(n), ins(n); 7 | vi r; 8 | auto dfs = [&](auto&& dfs, int u) { 9 | if (ins[u]) 10 | return false; 11 | if (!vis[u]) { 12 | ins[u] = 1; 13 | foreach (v, g[u]) 14 | if (!dfs(dfs, v)) 15 | return false; 16 | vis[u] = 1; 17 | r.eb(u); 18 | ins[u] = 0; 19 | } 20 | return true; 21 | }; 22 | _for (i, n) 23 | if (!vis[i] && !dfs(dfs, i)) 24 | return std::nullopt; 25 | reverse(r); 26 | return r; 27 | } -------------------------------------------------------------------------------- /graph/tree_all_distances.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/centroid_decomposition.hpp" 3 | #include "poly/convolution.hpp" 4 | 5 | vc tree_all_distances(const auto& g) { 6 | const int n = g.n; 7 | vc ans(n); 8 | ans[0] = n; 9 | ans[1] = n + n - 2; 10 | auto f = [&](auto&& par, auto&& V, int n1, int n2) { 11 | int n = len(V); 12 | vi dist(n); 13 | _for (i, 1, n) 14 | dist[i] = dist[par[i]] + 1; 15 | int mx = max(dist); 16 | vi f(mx + 1), g(mx + 1); 17 | _for (i, 1, n1 + 1) 18 | f[dist[i]]++; 19 | _for (i, n1 + 1, n1 + n2 + 1) 20 | g[dist[i]]++; 21 | while (f.back() == 0) 22 | f.pop_back(); 23 | while (g.back() == 0) 24 | g.pop_back(); 25 | auto r = convolution(f, g); 26 | _for (i, len(r)) 27 | ans[i] += r[i] * 2; 28 | }; 29 | centroid_decomposition<1>(g, f); 30 | return ans; 31 | } -------------------------------------------------------------------------------- /graph/tree_monoid.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/tree_monoid_base.hpp" 3 | #include "ds/segtree.hpp" 4 | 5 | template 6 | using Tree_Monoid = Tree_Monoid_Base; -------------------------------------------------------------------------------- /graph/two_edge_component.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/base.hpp" 3 | 4 | struct TwoEdgeComponentResult { 5 | int id; 6 | vi comp; 7 | }; 8 | auto two_edge_component(const UndirectedGraph auto& g) { 9 | const int n = g.n, m = g.m; 10 | vi par(n, -2), dp(n), V; 11 | V.reserve(n); 12 | vcb used(m); 13 | auto dfs = [&](auto&& dfs, int u) -> void { 14 | V.eb(u); 15 | foreach (v, g[u]) 16 | if (!used[v.id]) { 17 | used[v.id] = 1; 18 | if (par[v] == -2) { 19 | par[v] = u; 20 | dfs(dfs, v); 21 | } 22 | else { 23 | dp[u]++; 24 | dp[v]--; 25 | } 26 | } 27 | }; 28 | _for (u, n) 29 | if (par[u] == -2) 30 | par[u] = -1, dfs(dfs, u); 31 | _for_r (i, n) 32 | if (par[V[i]] != -1) 33 | dp[par[V[i]]] += dp[V[i]]; 34 | int id = 0; 35 | vi comp(n); 36 | foreach (u, V) 37 | comp[u] = !dp[u] ? id++ : comp[par[u]]; 38 | return TwoEdgeComponentResult{id, std::move(comp)}; 39 | } -------------------------------------------------------------------------------- /graph/twosat.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/strongly_connected_component.hpp" 3 | 4 | struct TwoSat { 5 | Graph g; 6 | vi values; 7 | 8 | TwoSat(int n): g(n << 1), values(n, -1) {} 9 | void add(int a, int b) { 10 | a = a >= 0 ? a << 1 | 1 : ~a << 1; 11 | b = b >= 0 ? b << 1 | 1 : ~b << 1; 12 | g.add(a ^ 1, b); 13 | g.add(b ^ 1, a); 14 | } 15 | void set(int a) { 16 | if (a >= 0) 17 | values[a] = 1; 18 | else 19 | values[~a] = 0; 20 | a = a >= 0 ? a << 1 | 1 : ~a << 1; 21 | g.add(a ^ 1, a); 22 | } 23 | std::optional solve() { 24 | g.build(); 25 | int n = len(values); 26 | auto comp = strongly_connected_component(g).comp; 27 | _for (i, n) { 28 | if (comp[i << 1] == comp[i << 1 | 1]) 29 | return std::nullopt; 30 | values[i] = comp[i << 1] < comp[i << 1 | 1]; 31 | } 32 | return values; 33 | } 34 | }; -------------------------------------------------------------------------------- /graph/utility.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/bfs01.hpp" 3 | #include "graph/restore_path.hpp" 4 | 5 | template 6 | struct DiameterResult { 7 | T diam; 8 | vi path; 9 | }; 10 | template 11 | auto diameter(const auto& g) { 12 | auto [d1, _] = bfs01(g, 0); 13 | int u = max_element(d1) - d1.begin(); 14 | auto [d2, par] = bfs01(g, u); 15 | int v = max_element(d2) - d2.begin(); 16 | return DiameterResult{d2[v], restore_path(par, v)}; 17 | } 18 | 19 | vi get_path(const auto& g, int u, int v) { 20 | vi r; 21 | auto dfs = [&](auto&& dfs, int u, int f) -> bool { 22 | r.eb(u); 23 | if (u == v) 24 | return true; 25 | foreach (v, g[u]) 26 | if (v != f && dfs(dfs, v, u)) 27 | return true; 28 | r.pop_back(); 29 | return false; 30 | }; 31 | dfs(dfs, u, -1); 32 | return r; 33 | } -------------------------------------------------------------------------------- /graph/vs_to_es.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/base.hpp" 3 | #include "ds/hashmap.hpp" 4 | 5 | template 6 | vi vs_to_es(const auto& g, const vi& vs) { 7 | const int n = g.n, m = g.m; 8 | ASSERT(!vs.empty()); 9 | 10 | HashMap mp; 11 | vi nxt(m, -1); 12 | auto get = [&](int a, int b) { 13 | if (g.is_directed() && a > b) 14 | swap(a, b); 15 | return u64(a) * n + b; 16 | }; 17 | _for (i, m) { 18 | u64 k = get(g.edges[i].from, g.edges[i].to); 19 | nxt[i] = std::exchange(mp[k], i); 20 | } 21 | vi es(len(vs) - 1); 22 | _for (i, len(es)) { 23 | u64 k = get(vs[i], vs[i + 1]); 24 | int e = mp.get(k, -1); 25 | ASSERT(e != -1); 26 | es[i] = e; 27 | if constexpr (!allow_twice) 28 | mp[k] = nxt[e]; 29 | } 30 | return es; 31 | } -------------------------------------------------------------------------------- /io/dummy.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | struct DummyReader { 5 | static constexpr int ev{}; 6 | DummyReader(auto) {} 7 | int getch(); 8 | int getch_unchecked(); 9 | int peek() const; 10 | void ireadstr(char*, usize); 11 | void skipws(); 12 | void rd(char*); 13 | void rd(str&); 14 | void readline(char*); 15 | void readline(str&); 16 | void readstr(char*, usize); 17 | void readstr(str&, usize); 18 | char*& raw_ip(); 19 | template 20 | void ensure(); 21 | }; 22 | struct DummyWriter { 23 | DummyWriter(auto) {} 24 | void putch(char); 25 | void putch_unchecked(char); 26 | void writestr(const char*, usize); 27 | void flush() {} 28 | template 29 | void ensure(); 30 | }; -------------------------------------------------------------------------------- /io/fwritewriter.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | struct FwriteWriter { 5 | FILE* out; 6 | char obuf[1 << 20], *op = obuf; 7 | FwriteWriter(FILE* f): out(f) {} 8 | FwriteWriter(std::string_view s): FwriteWriter(fopen(s.data(), "w")) {} 9 | void putch(char c) { 10 | if (op == end(obuf)) 11 | flush(); 12 | putch_unchecked(c); 13 | } 14 | void putch_unchecked(char c) { *op++ = c; } 15 | void writestr(const char* s, usize n) { 16 | if (n >= usize(end(obuf) - op)) [[unlikely]] 17 | flush(), fwrite(s, 1, n, out); 18 | else 19 | memcpy(op, s, n), op += n; 20 | } 21 | void flush() { fwrite(obuf, 1, op - obuf, out), op = obuf; } 22 | template 23 | void ensure() { 24 | if (end(obuf) - op < N) [[unlikely]] 25 | flush(); 26 | } 27 | }; -------------------------------------------------------------------------------- /linalg/matrix_inv.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | std::pair, T> matrix_inv(vvc a) { 6 | const int n = len(a); 7 | ASSERT(n == len(a[0])); 8 | VEC(T, b, n, n); 9 | _for (i, n) 10 | b[i][i] = 1; 11 | T det = 1; 12 | _for (i, n) { 13 | _for (j, i, n) 14 | if (a[j][i] != 0) { 15 | if (i != j) { 16 | swap(a[i], a[j]); 17 | swap(b[i], b[j]); 18 | det = -det; 19 | } 20 | break; 21 | } 22 | if (a[i][i] == 0) 23 | return {}; 24 | det *= a[i][i]; 25 | T inv = 1 / a[i][i]; 26 | _for (j, i, n) 27 | a[i][j] *= inv; 28 | _for (j, n) 29 | b[i][j] *= inv; 30 | _for (j, n) 31 | if (i != j) { 32 | T c = a[j][i]; 33 | _for (k, i, n) 34 | a[j][k] -= a[i][k] * c; 35 | _for (k, n) 36 | b[j][k] -= b[i][k] * c; 37 | } 38 | } 39 | return {std::move(b), det}; 40 | } -------------------------------------------------------------------------------- /linalg/matrix_mul.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "linalg/transpose.hpp" 3 | 4 | template 5 | vvc matrix_mul(const vvc& a, const vvc& b) { 6 | int n0 = len(a), n1 = len(b), n2 = len(b[0]); 7 | ASSERT(n1 == len(a[0])); 8 | auto t = transpose(b); 9 | VEC(T, c, n0, n2); 10 | _for (i, n0) 11 | _for (j, n2) 12 | _for (k, n1) 13 | c[i][j] += a[i][k] * t[j][k]; 14 | return c; 15 | } -------------------------------------------------------------------------------- /linalg/matrix_pow.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "linalg/frobenius.hpp" 3 | 4 | template 5 | vvc matrix_pow(vvc a, auto k) { 6 | const int n = len(a); 7 | ASSERT(n == len(a[0])); 8 | VEC(T, ans, n, n); 9 | _for (i, n) 10 | ans[i][i] = 1; 11 | for (; k; k >>= 1, a *= a) 12 | if (k & 1) 13 | ans *= a; 14 | return ans; 15 | } 16 | template 17 | vvc matrix_pow(const vvc& a, auto k) { return Frobenius(a)(k); } -------------------------------------------------------------------------------- /linalg/transpose.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | vc transpose(const vc& a) { 6 | int n = len(a), m = len(a[0]); 7 | vc b(m, V(n, decltype(a[0][0]){})); 8 | _for (i, n) 9 | _for (j, m) 10 | b[j][i] = a[i][j]; 11 | return b; 12 | } -------------------------------------------------------------------------------- /math/binary_search.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | T bsearch(auto&& check, T ok, T ng) { 6 | while (std::abs(ok - ng) > 1) { 7 | T x = (ng + ok) >> 1; 8 | (check(x) ? ok : ng) = x; 9 | } 10 | return ok; 11 | } 12 | template 13 | T bsearch(auto&& check, T ok, T ng, int iter = 100) { 14 | _for (iter) { 15 | T x = (ng + ok) / 2; 16 | (check(x) ? ok : ng) = x; 17 | } 18 | return (ng + ok) / 2; 19 | } -------------------------------------------------------------------------------- /math/divisors.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "math/factorize.hpp" 3 | 4 | template 5 | vc divisors(T n) { 6 | vc d{1}; 7 | foreach (p, c, factorize_pair(n)) { 8 | int t = len(d); 9 | T pp = 1; 10 | _for (c) { 11 | pp *= p; 12 | _for (i, t) 13 | d.eb(d[i] * pp); 14 | } 15 | } 16 | return d; 17 | } 18 | vi divisors(int n, const vi& lpf) { 19 | vi d{1}; 20 | foreach (p, c, factorize_pair(n, lpf)) { 21 | int t = len(d); 22 | int pp = 1; 23 | _for (c) { 24 | pp *= p; 25 | _for (i, t) 26 | d.eb(d[i] * pp); 27 | } 28 | } 29 | return d; 30 | } -------------------------------------------------------------------------------- /math/euler_phi.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "math/factorize.hpp" 3 | #include "math/zeta.hpp" 4 | 5 | template 6 | T euler_phi(T n) { 7 | foreach (p, _, factorize_pair(n)) 8 | n -= n / p; 9 | return n; 10 | } 11 | vi euler_phi_table(int n) { 12 | vi a(n + 1); 13 | iota(all(a), 0); 14 | divisor_mobius(a); 15 | return a; 16 | } -------------------------------------------------------------------------------- /math/exgcd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | std::tuple exgcd(T a, T b) { 6 | if (!b) 7 | return {1, 0, a}; 8 | auto [x, y, d] = exgcd(b, a % b); 9 | return {y, x - (a / b) * y, d}; 10 | } -------------------------------------------------------------------------------- /math/fixpoint.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | T fixpoint(T x, auto&& f) { 6 | T xn = f(x); 7 | while (x < xn) { 8 | x = xn; 9 | xn = f(x); 10 | } 11 | while (xn < x) { 12 | x = xn; 13 | xn = f(x); 14 | } 15 | return x; 16 | } -------------------------------------------------------------------------------- /math/gcd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | int ctz(T x) { 6 | if constexpr (sizeof(T) <= 4) 7 | return __builtin_ctz(x); 8 | else if constexpr (sizeof(T) == 8) 9 | return __builtin_ctzll(x); 10 | else if (u64(x)) 11 | return ctz(u64(x)); 12 | else 13 | return 64 + ctz(x >> 64); 14 | } 15 | 16 | template 17 | constexpr auto gcd(T _a, U _b) { 18 | using S = make_signed_t>; 19 | S a = _a >= 0 ? _a : -_a, b = _b >= 0 ? _b : -_b; 20 | if (a == 0) 21 | return b; 22 | if (b == 0) 23 | return a; 24 | int i = ctz(a); 25 | int j = ctz(b); 26 | int k = min(i, j); 27 | b >>= j; 28 | while (a != 0) { 29 | a >>= i; 30 | S diff = b - a; 31 | i = ctz(diff); 32 | chkmin(b, a); 33 | a = std::abs(diff); 34 | } 35 | return b << k; 36 | } -------------------------------------------------------------------------------- /math/icbrt.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "math/fixpoint.hpp" 3 | 4 | template 5 | T icbrt(T a) { 6 | if (a < 8) 7 | return a > 0; 8 | if (a <= u32(-1)) { 9 | T x = a; 10 | T y2 = 0; 11 | T y = 0; 12 | T smax = std::numeric_limits::digits / 3; 13 | _for_r (s, smax + 1) { 14 | T t = s * 3; 15 | y2 *= 4; 16 | y *= 2; 17 | T b = 3 * (y2 + y) + 1; 18 | if ((x >> t) >= b) { 19 | x -= b << t; 20 | y2 += 2 * y + 1; 21 | y += 1; 22 | } 23 | } 24 | return y; 25 | } 26 | auto guess = [&](T x) -> T { return cbrt(x); }; 27 | auto next = [&](T x) { return (a / (x * x) + 2 * x) / 3; }; 28 | return fixpoint(guess(a), next); 29 | } 30 | template 31 | T icbrt(T a) { 32 | if (a >= 0) 33 | return icbrt>(a); 34 | return -icbrt>(-a); 35 | } -------------------------------------------------------------------------------- /math/isqrt.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "math/fixpoint.hpp" 3 | 4 | template 5 | T isqrt(T a) { 6 | if (a < 4) 7 | return a > 0; 8 | auto guess = [&](T x) -> T { return sqrt(x); }; 9 | auto next = [&](T x) { return (a / x + x) >> 1; }; 10 | return fixpoint(guess(a), next); 11 | } 12 | template 13 | T isqrt(T a) { 14 | ASSERT(a >= 0); 15 | return isqrt>(a); 16 | } -------------------------------------------------------------------------------- /math/lcm.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "math/factorize.hpp" 3 | #include "ds/hashmap.hpp" 4 | 5 | template 6 | R lcm(const vi& a) { 7 | if (a.empty()) 8 | return 1; 9 | HashMap mp; 10 | foreach (x, a) 11 | foreach (p, c, factorize_pair(x)) 12 | chkmax(mp[p], c); 13 | R x = 1; 14 | foreach (p, c, mp) 15 | x *= power(p, c); 16 | return x; 17 | } 18 | template 19 | R lcm(const vi& a, const vi& lpf) { 20 | if (a.empty()) 21 | return 1; 22 | HashMap mp; 23 | foreach (x, a) 24 | foreach (p, c, factorize_pair(x, lpf)) 25 | chkmax(mp[p], c); 26 | R x = 1; 27 | foreach (p, c, mp) 28 | x *= power(p, c); 29 | return x; 30 | } -------------------------------------------------------------------------------- /math/lpf_table.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "math/prime/sieve.hpp" 3 | 4 | vi lpf_table(int n) { 5 | auto primes = prime_sieve(n); 6 | vi r(n + 1, -1); 7 | _for_r (i, len(primes)) { 8 | int p = primes[i]; 9 | _for (j, p, n + 1, p) 10 | r[j] = p; 11 | } 12 | return r; 13 | } -------------------------------------------------------------------------------- /math/mobius_table.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "math/zeta.hpp" 3 | 4 | template 5 | vc mobius_table(int n) { 6 | vc mu(n + 1); 7 | mu[1] = 1; 8 | divisor_mobius(mu); 9 | return mu; 10 | } -------------------------------------------------------------------------------- /math/mod_inverse.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template > 5 | constexpr std::tuple bezout(T x, T y) { 6 | bool t = x < y; 7 | if (t) 8 | swap(x, y); 9 | if (y == 0) { 10 | if (x == 0) 11 | return {}; 12 | if (t) 13 | return {0, 1, x}; 14 | return {1, 0, x}; 15 | } 16 | S s0 = 1, s1 = 0, t0 = 0, t1 = 1; 17 | loop { 18 | auto [q, r] = divmod(x, y); 19 | if (r == 0) { 20 | if (t) 21 | return {t1, s1, y}; 22 | return {s1, t1, y}; 23 | } 24 | S s2 = s0 - S(q) * s1, t2 = t0 - S(q) * t1; 25 | x = y; 26 | y = r; 27 | s0 = s1; 28 | s1 = s2; 29 | t0 = t1; 30 | t1 = t2; 31 | } 32 | } 33 | template 34 | constexpr T mod_inverse(T x, T m) { 35 | auto [s, t, g] = bezout(x, m); 36 | ASSERT(g == 1); 37 | return s < 0 ? T(s) + m : s; 38 | } -------------------------------------------------------------------------------- /math/power.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | constexpr T power(T a, auto b) { 5 | T ans{1}; 6 | for (; b; b >>= 1, a *= a) 7 | if (b & 1) 8 | ans *= a; 9 | return ans; 10 | } -------------------------------------------------------------------------------- /math/prime/test.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "modint/montgomery.hpp" 3 | 4 | constexpr bool is_prime(auto x) { 5 | auto is_prime = [](auto x) -> bool { 6 | if (x < 64) 7 | return 0x28208a20a08a28ac >> x & 1; 8 | if (x % 2 == 0 || x % 3 == 0 || x % 5 == 0 || x % 7 == 0) 9 | return false; 10 | if (x < 121) 11 | return true; 12 | using T = decltype(x); 13 | SetMMod(T, x); 14 | const T d = (x - 1) >> std::countr_zero(x - 1); 15 | auto mr = [&](T a) { 16 | const mint one = 1, mone = -1; 17 | auto y = power(a, d); 18 | T t = d; 19 | while (y != one && y != mone && t != x - 1) 20 | y *= y, t <<= 1; 21 | return y == mone || t % 2; 22 | }; 23 | if (x < (1ULL << 32)) 24 | return mr(2) && mr(7) && mr(61); 25 | for (T a: {2, 325, 9375, 28178, 450775, 9780504, 1795265022}) 26 | if (!mr(a)) 27 | return false; 28 | return true; 29 | }; 30 | if (x < (1 << 30)) 31 | return is_prime(u32(x)); 32 | return is_prime(u64(x)); 33 | } 34 | -------------------------------------------------------------------------------- /math/primitive_root.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "math/factorize.hpp" 3 | 4 | template 5 | T primitive_root(T mod) { 6 | if (mod == 2) 7 | return 1; 8 | auto pf = factorize(mod - 1); 9 | SetMMod(T, mod); 10 | loop { 11 | T pr = rnd(2, mod); 12 | foreach (p, pf) 13 | if (power(pr, (mod - 1) / p) == 1) 14 | goto cont; 15 | return pr; 16 | cont:; 17 | } 18 | } -------------------------------------------------------------------------------- /math/primitive_root_constexpr.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | constexpr u32 primitive_root_constexpr(u32 mod) { 5 | if (mod == 2) 6 | return 1; 7 | u64 ds[32]{}; 8 | int idx = 0; 9 | u64 m = mod - 1; 10 | for (u64 i = 2; i * i <= m; i++) 11 | if (m % i == 0) { 12 | ds[idx++] = i; 13 | while (m % i == 0) 14 | m /= i; 15 | } 16 | if (m != 1) 17 | ds[idx++] = m; 18 | u32 pr = 1; 19 | loop { 20 | pr++; 21 | bool ok = true; 22 | _for (i, idx) { 23 | u64 a = pr, b = (mod - 1) / ds[i], r = 1; 24 | while (b) { 25 | if (b & 1) 26 | r = r * a % mod; 27 | a = a * a % mod; 28 | b >>= 1; 29 | } 30 | if (r == 1) { 31 | ok = false; 32 | break; 33 | } 34 | } 35 | if (ok) 36 | return pr; 37 | } 38 | } -------------------------------------------------------------------------------- /math/zeta.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "math/prime/sieve.hpp" 3 | 4 | template 5 | void divisor_zeta(vc& a) { 6 | ASSERT(a[0] == 0); 7 | int n = len(a) - 1; 8 | foreach (p, prime_sieve(n)) 9 | _for (x, 1, n / p + 1) 10 | a[p * x] += a[x]; 11 | } 12 | 13 | template 14 | void divisor_mobius(vc& a) { 15 | ASSERT(a[0] == 0); 16 | int n = len(a) - 1; 17 | foreach (p, prime_sieve(n)) 18 | _for_r (x, 1, n / p + 1) 19 | a[p * x] -= a[x]; 20 | } 21 | 22 | template 23 | void multiplier_zeta(vc& a) { 24 | ASSERT(a[0] == 0); 25 | int n = len(a) - 1; 26 | foreach (p, prime_sieve(n)) 27 | _for_r (x, 1, n / p + 1) 28 | a[x] += a[p * x]; 29 | } 30 | 31 | template 32 | void multiplier_mobius(vc& a) { 33 | ASSERT(a[0] == 0); 34 | int n = len(a) - 1; 35 | foreach (p, prime_sieve(n)) 36 | _for (x, 1, n / p + 1) 37 | a[x] -= a[p * x]; 38 | } -------------------------------------------------------------------------------- /modint/all_inverse.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | vc all_inverse(vc& a) { 6 | const int n = len(a); 7 | vc r(n + 1); 8 | r[0] = 1; 9 | _for (i, n) 10 | r[i + 1] = r[i] * a[i]; 11 | mint t = pop(r).inv(); 12 | _for_r (i, n) { 13 | r[i] *= t; 14 | t *= a[i]; 15 | } 16 | return r; 17 | } -------------------------------------------------------------------------------- /modint/mod_log.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "modint/barrett.hpp" 3 | #include "monoid/mul.hpp" 4 | #include "math/discrete_log.hpp" 5 | 6 | template 7 | std::optional mod_log(mint a, mint b) { 8 | return discrete_log_monoid>(a, b, [&](mint x) { return x.val(); }, 0, mint::mod()); 9 | } 10 | template 11 | std::optional mod_log(T a, T b, T p) { 12 | SetBMod(T, p); 13 | auto r = mod_log(a, b); 14 | if (r) 15 | return r->val(); 16 | return std::nullopt; 17 | } -------------------------------------------------------------------------------- /modint/mod_sqrt.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "modint/montgomery.hpp" 3 | 4 | template 5 | std::optional mod_sqrt(mint a) { 6 | if (a < 2) 7 | return a; 8 | auto k = (mint::mod() - 1) >> 1; 9 | if (power(a, k) != 1) 10 | return std::nullopt; 11 | mint b = 1, D = 1 - a; 12 | while (power(D, k) == 1) 13 | ++b, D = b * b - a; 14 | k++; 15 | mint f0 = b, f1 = 1, g0 = 1, g1 = 0; 16 | while (k) { 17 | if (k & 1) 18 | std::tie(g0, g1) = std::pair{f0 * g0 + D * f1 * g1, f0 * g1 + f1 * g0}; 19 | std::tie(f0, f1) = std::pair{f0 * f0 + D * f1 * f1, 2 * f0 * f1}; 20 | k >>= 1; 21 | } 22 | return g0; 23 | } 24 | template 25 | std::optional mod_sqrt(T a, T p) { 26 | if (a < 2) 27 | return a; 28 | SetMMod(T, p); 29 | auto r = mod_sqrt(a); 30 | if (r) 31 | return r->val(); 32 | return std::nullopt; 33 | } -------------------------------------------------------------------------------- /modint/modint_common.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "math/mod_inverse.hpp" 3 | #include "math/power.hpp" 4 | 5 | template 6 | auto val(const T& x) { 7 | if constexpr (Modint) 8 | return x.val(); 9 | else 10 | return x; 11 | } -------------------------------------------------------------------------------- /monoid/add.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct Monoid_Add { 5 | using value_type = T; 6 | using X = value_type; 7 | static constexpr auto op(auto&& a, auto&& b) { return a + b; } 8 | static constexpr X inverse(const X& x) { return -x; } 9 | static constexpr X power(const X& x, auto n) { return n * x; } 10 | static constexpr X from_element(auto&& x) { return x; } 11 | static constexpr X unit() { return {}; } 12 | static constexpr bool commute() { return true; } 13 | }; -------------------------------------------------------------------------------- /monoid/add_array.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct Monoid_AddArray { 6 | using value_type = std::array; 7 | using X = value_type; 8 | static constexpr X op(X a, const X& b) { 9 | _for (i, N) 10 | a[i] += b[i]; 11 | return a; 12 | } 13 | static constexpr X inverse(X x) { 14 | foreach (x, x) 15 | x = -x; 16 | return x; 17 | } 18 | static constexpr X power(X x, auto n) { 19 | foreach (x, x) 20 | x *= n; 21 | return x; 22 | } 23 | static constexpr X from_element(auto&& x) { return x; } 24 | static constexpr X unit() { return {}; } 25 | static constexpr bool commute() { return true; } 26 | }; -------------------------------------------------------------------------------- /monoid/addmax.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/add.hpp" 3 | #include "monoid/max.hpp" 4 | #include "monoid/monoid_combine.hpp" 5 | 6 | template 7 | using Monoid_AddMax = Monoid_Combine, Monoid_Max>; -------------------------------------------------------------------------------- /monoid/addmin.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/add.hpp" 3 | #include "monoid/min.hpp" 4 | #include "monoid/monoid_combine.hpp" 5 | 6 | template 7 | using Monoid_AddMin = Monoid_Combine, Monoid_Min>; -------------------------------------------------------------------------------- /monoid/addminmax.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/add.hpp" 3 | #include "monoid/min.hpp" 4 | #include "monoid/max.hpp" 5 | #include "monoid/monoid_combine.hpp" 6 | 7 | template 8 | using Monoid_AddMinMax = Monoid_Combine, Monoid_Min, Monoid_Max>; -------------------------------------------------------------------------------- /monoid/affine.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct Monoid_Affine { 6 | using value_type = std::pair; 7 | using X = value_type; 8 | static constexpr X op(const X& a, const X& b) { return {a.first * b.first, a.second * b.first + b.second}; } 9 | static constexpr X inverse(const X& x) { 10 | X t = 1 / x.first; 11 | return {t, -t * x.second}; 12 | } 13 | static constexpr T eval(const X& x, T y) { return x.first * y + x.second; } 14 | static constexpr X from_element(auto&& x) { return x; } 15 | static constexpr X unit() { return {1, 0}; } 16 | static constexpr bool commute() { return false; } 17 | }; -------------------------------------------------------------------------------- /monoid/and.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct Monoid_And { 5 | using value_type = T; 6 | using X = value_type; 7 | static constexpr X op(const X& a, const X& b) { return a & b; } 8 | static constexpr X from_element(auto&& x) { return x; } 9 | static constexpr X unit() { return -1; } 10 | static constexpr bool commute() { return true; } 11 | }; -------------------------------------------------------------------------------- /monoid/assign.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template > 5 | struct Monoid_Assign { 6 | using value_type = T; 7 | using X = value_type; 8 | static constexpr X op(const X& a, const X& b) { return b == none ? a : b; } 9 | static constexpr X from_element(auto&& x) { return x; } 10 | static constexpr X unit() { return none; } 11 | static constexpr bool commute() { return false; } 12 | }; -------------------------------------------------------------------------------- /monoid/gcd.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "math/gcd.hpp" 3 | 4 | template 5 | struct Monoid_Gcd { 6 | using value_type = T; 7 | using X = value_type; 8 | static constexpr X op(const X& a, const X& b) { return binary_gcd(a, b); } 9 | static constexpr X unit() { return {}; } 10 | static constexpr bool commute() { return true; } 11 | }; -------------------------------------------------------------------------------- /monoid/max.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct Monoid_Max { 6 | using value_type = T; 7 | using X = value_type; 8 | static constexpr X op(const X& a, const X& b) { return Max(a, b); } 9 | static constexpr X from_element(auto&& x) { return x; } 10 | static constexpr X unit() { return -inf; } 11 | static constexpr bool commute() { return true; } 12 | }; -------------------------------------------------------------------------------- /monoid/max2.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct Monoid_Max2 { 6 | using value_type = std::pair; 7 | using X = value_type; 8 | static constexpr X op(const X& a, const X& b) { 9 | if (a.first == b.first) 10 | return {a.first, max(a.second, b.second)}; 11 | if (a.first > b.first) 12 | return {a.first, max(a.second, b.first)}; 13 | return {b.first, max(b.second, a.first)}; 14 | } 15 | static constexpr X from_element(auto&& x) { return {x, -inf}; } 16 | static constexpr X unit() { return {-inf, -inf}; } 17 | static constexpr bool commute() { return true; } 18 | }; -------------------------------------------------------------------------------- /monoid/max_idx.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct Monoid_Max_Idx { 6 | using value_type = std::pair; 7 | using X = value_type; 8 | static constexpr X op(const X& a, const X& b) { 9 | if (a.first > b.first) 10 | return a; 11 | if (a.first < b.first) 12 | return b; 13 | if constexpr (less) 14 | return a.second < b.second ? a : b; 15 | else 16 | return a.second > b.second ? a : b; 17 | } 18 | static constexpr X from_element(auto&& x) { return {x, -1}; } 19 | static constexpr X unit() { return {-inf, -1}; } 20 | static constexpr bool commute() { return true; } 21 | }; -------------------------------------------------------------------------------- /monoid/maxmaxcnt.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct Monoid_MaxMaxcnt { 6 | using value_type = std::pair; 7 | using X = value_type; 8 | static constexpr X op(const X& a, const X& b) { 9 | if (a.first > b.first) 10 | return a; 11 | if (a.first < b.first) 12 | return b; 13 | return {a.first, a.second + b.second}; 14 | } 15 | static constexpr X from_element(auto&& x) { return {x, 1}; } 16 | static constexpr X unit() { return {-inf, 0}; } 17 | static constexpr bool commute() { return true; } 18 | }; -------------------------------------------------------------------------------- /monoid/merge_vector_space.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "linalg/vector_space.hpp" 3 | 4 | template 5 | struct Merge_Vector_Space { 6 | using value_type = Vector_Space; 7 | using X = value_type; 8 | static X op(const X& a, const X& b) { return X::merge(a, b); } 9 | static X from_element(auto&& x) { return x; } 10 | static X unit() { return {}; } 11 | static constexpr bool commute() { return true; } 12 | }; -------------------------------------------------------------------------------- /monoid/min.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct Monoid_Min { 6 | using value_type = T; 7 | using X = value_type; 8 | static constexpr X op(const X& a, const X& b) { return Min(a, b); } 9 | static constexpr X from_element(auto&& x) { return x; } 10 | static constexpr X unit() { return inf; } 11 | static constexpr bool commute() { return true; } 12 | }; -------------------------------------------------------------------------------- /monoid/min2.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct Monoid_Min2 { 6 | using value_type = std::pair; 7 | using X = value_type; 8 | static constexpr X op(const X& a, const X& b) { 9 | if (a.first == b.first) 10 | return {a.first, min(a.second, b.second)}; 11 | if (a.first < b.first) 12 | return {a.first, min(a.second, b.first)}; 13 | return {b.first, min(b.second, a.first)}; 14 | } 15 | static constexpr X from_element(auto&& x) { return {x, inf}; } 16 | static constexpr X unit() { return {inf, inf}; } 17 | static constexpr bool commute() { return true; } 18 | }; -------------------------------------------------------------------------------- /monoid/min_idx.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct Monoid_Min_Idx { 6 | using value_type = std::pair; 7 | using X = value_type; 8 | static constexpr X op(const X& a, const X& b) { 9 | if (a.first < b.first) 10 | return a; 11 | if (a.first > b.first) 12 | return b; 13 | if constexpr (less) 14 | return a.second < b.second ? a : b; 15 | else 16 | return a.second > b.second ? a : b; 17 | } 18 | static constexpr X from_element(auto&& x) { return {x, -1}; } 19 | static constexpr X unit() { return {inf, -1}; } 20 | static constexpr bool commute() { return true; } 21 | }; -------------------------------------------------------------------------------- /monoid/minmax.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "monoid/min.hpp" 3 | #include "monoid/max.hpp" 4 | #include "monoid/monoid_combine.hpp" 5 | 6 | template 7 | using Monoid_MinMax = Monoid_Combine, Monoid_Max>; -------------------------------------------------------------------------------- /monoid/minmincnt.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct Monoid_MinMincnt { 6 | using value_type = std::pair; 7 | using X = value_type; 8 | static constexpr X op(const X& a, const X& b) { 9 | if (a.first < b.first) 10 | return a; 11 | if (a.first > b.first) 12 | return b; 13 | return {a.first, a.second + b.second}; 14 | } 15 | static constexpr X from_element(auto&& x) { return {x, 1}; } 16 | static constexpr X unit() { return {inf, 0}; } 17 | static constexpr bool commute() { return true; } 18 | }; -------------------------------------------------------------------------------- /monoid/monoid_combine.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct Monoid_Combine { 6 | using value_type = std::tuple; 7 | using X = value_type; 8 | static constexpr X op(const X& a, const X& b) { 9 | return [&](std::index_sequence) -> X { return {M::op(std::get(a), std::get(b))...}; }(std::index_sequence_for{}); 10 | } 11 | static constexpr X inverse(const X& x) { 12 | return [&](std::index_sequence) -> X { return {M::inverse(std::get(x))...}; }(std::index_sequence_for{}); 13 | } 14 | static constexpr X power(const X& x, auto n) { 15 | return [&](std::index_sequence) -> X { return {M::power(std::get(x), n)...}; }(std::index_sequence_for{}); 16 | } 17 | static constexpr X from_element(auto&& x) { return {M::from_element(x)...}; } 18 | static constexpr X unit() { return {M::unit()...}; } 19 | static constexpr bool commute() { return (M::commute() && ...); } 20 | }; -------------------------------------------------------------------------------- /monoid/monoid_reverse.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct Monoid_Reverse { 5 | using value_type = M::value_type; 6 | using X = value_type; 7 | static constexpr X op(const X& a, const X& b) { return M::op(b, a); } 8 | static constexpr X from_element(auto&& x) { return x; } 9 | static constexpr X unit() { return M::unit(); } 10 | static constexpr bool commute() { return M::commute(); } 11 | }; -------------------------------------------------------------------------------- /monoid/moore.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | // Moore's Voting Algorithm 5 | template > 6 | struct Monoid_Moore { 7 | using value_type = std::pair; 8 | using X = value_type; 9 | static constexpr X op(const X& a, const X& b) { 10 | auto [x0, c0] = a; 11 | auto [x1, c1] = b; 12 | if (x0 == x1) 13 | return {x0, c0 + c1}; 14 | if (c0 > c1 || x1 == none) 15 | return {x0, c0 - c1}; 16 | return {x1, c1 - c0}; 17 | } 18 | static constexpr X from_element(auto&& x) { return {x, 1}; } 19 | static constexpr X unit() { return {none, 0}; } 20 | static constexpr bool commute() { return true; } 21 | }; -------------------------------------------------------------------------------- /monoid/mul.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct Monoid_Mul { 5 | using value_type = T; 6 | using X = value_type; 7 | static constexpr X op(const X& a, const X& b) { return a * b; } 8 | static constexpr X inverse(const X& x) { return 1 / x; } 9 | static constexpr X from_element(auto&& x) { return x; } 10 | static constexpr X unit() { return 1; } 11 | static constexpr bool commute() { return true; } 12 | }; -------------------------------------------------------------------------------- /monoid/or.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct Monoid_Or { 5 | using value_type = T; 6 | using X = value_type; 7 | static constexpr X op(const X& a, const X& b) { return a | b; } 8 | static constexpr X from_element(auto&& x) { return x; } 9 | static constexpr X unit() { return {}; } 10 | static constexpr bool commute() { return true; } 11 | }; -------------------------------------------------------------------------------- /monoid/rollinghash.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "random/base.hpp" 3 | #include "modint/mint61.hpp" 4 | 5 | template 6 | struct Monoid_Rollinghash { 7 | using value_type = std::pair; 8 | using X = value_type; 9 | 10 | static u64 generateBase() { return rnd(1, mint::mod()); } 11 | static inline const mint base = generateBase(); 12 | 13 | static constexpr X op(const X& a, const X& b) { return {a.first * b.first, a.second * b.first + b.second}; } 14 | static constexpr X from_element(auto&& x) { return {base, x}; } 15 | static constexpr X unit() { return {1, 0}; } 16 | static constexpr bool commute() { return false; } 17 | }; -------------------------------------------------------------------------------- /monoid/xor.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct Monoid_Xor { 5 | using value_type = T; 6 | using X = value_type; 7 | static constexpr auto op(auto&& a, auto&& b) { return a ^ b; } 8 | static constexpr X inverse(const X& x) { return x; } 9 | static constexpr X power(const X& x, auto n) { return n & 1 ? x : 0; } 10 | static constexpr X from_element(auto&& x) { return x; } 11 | static constexpr X unit() { return {}; } 12 | static constexpr bool commute() { return true; } 13 | }; -------------------------------------------------------------------------------- /poly/arbitrary_ntt.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "modint/montgomery.hpp" 3 | 4 | namespace ArbitraryNTT { 5 | constexpr u32 m0 = 167772161; 6 | constexpr u32 m1 = 469762049; 7 | constexpr u32 m2 = 754974721; 8 | using mint0 = MMInt; 9 | using mint1 = MMInt; 10 | using mint2 = MMInt; 11 | constexpr u32 r01 = mint1(m0).inv().val(); 12 | constexpr u32 r02 = mint2(m0).inv().val(); 13 | constexpr u32 r12 = mint2(m1).inv().val(); 14 | constexpr u32 r02r12 = u64(r02) * r12 % m2; 15 | constexpr u64 w1 = m0; 16 | constexpr u64 w2 = u64(m0) * m1; 17 | template 18 | void crt(auto&& c0, auto&& c1, auto&& c2, auto&& r, u64 w1, u64 w2) { 19 | _for (i, len(r)) { 20 | u64 n1 = val(c1[i]), n2 = val(c2[i]), a = val(c0[i]); 21 | u64 b = (n1 + m1 - a) * r01 % m1; 22 | u64 c = ((n2 + m2 - a) * r02r12 + (m2 - b) * r12) % m2; 23 | r[i] = a + b * w1 + T(c) * w2; 24 | } 25 | } 26 | } // namespace ArbitraryNTT -------------------------------------------------------------------------------- /poly/convolution_huge.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "poly/convolution.hpp" 3 | 4 | template 5 | vc convolution_huge(const vc& a, const vc& b) { 6 | constexpr NTT ntt; 7 | constexpr int k = ntt.lvl; 8 | constexpr int mask = (1 << (k - 1)) - 1; 9 | constexpr mint iv = mint(1 << k).inv(); 10 | int n = len(a), m = len(b); 11 | if (n + m - 1 <= (1 << k)) 12 | return convolution(a, b); 13 | VEC(mint, c, 4, 1 << k); 14 | VEC(mint, d, 4, 1 << k); 15 | _for (i, n) 16 | c[i >> (k - 1)][i & mask] = a[i]; 17 | _for (i, m) 18 | d[i >> (k - 1)][i & mask] = b[i]; 19 | _for (i, 4) 20 | fft4(c[i], k); 21 | _for (i, 4) 22 | fft4(d[i], k); 23 | vc ans(4 << k); 24 | _for (i, 7) { 25 | vc E(1 << k); 26 | _for (t, 4) 27 | if (0 <= i - t && i - t < 4) 28 | _for (j, 1 << k) 29 | E[j] += c[t][j] * d[i - t][j]; 30 | ifft4(E, k); 31 | _for (j, 1 << k) 32 | ans[(i << (k - 1)) + j] += E[j] * iv; 33 | } 34 | ans.resize(n + m - 1); 35 | return ans; 36 | } 37 | -------------------------------------------------------------------------------- /poly/convolution_naive.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | vc convolution_naive(const vc& a, const vc& b) { 6 | int n = len(a), m = len(b); 7 | if (n > m) 8 | return convolution_naive(b, a); 9 | if (!n) 10 | return {}; 11 | vc r(n + m - 1); 12 | _for (i, n) 13 | _for (j, m) 14 | r[i + j] += U(a[i]) * b[j]; 15 | return r; 16 | } -------------------------------------------------------------------------------- /random/base.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "seed.hpp" 3 | 4 | u64 rnd64() { 5 | u64& s = seed(); 6 | return s ^= s << 7, s ^= s >> 9; 7 | } 8 | i64 rnd(i64 l, i64 r) { 9 | return l + rnd64() % (r - l); 10 | } 11 | u32 rnd() { return rnd64(); } -------------------------------------------------------------------------------- /random/shuffle.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "random/base.hpp" 3 | 4 | void Shuffle(auto first, auto last) { 5 | for (auto it = first; it != last; ++it) 6 | std::iter_swap(it, first + rnd(0, it - first + 1)); 7 | } 8 | void Shuffle(auto&& r) { Shuffle(all(r)); } -------------------------------------------------------------------------------- /seed.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | namespace seed_impl { 5 | struct Seed { 6 | u64 seed; 7 | Seed() { 8 | #if defined(LX_LOCAL) && !defined(RANDOM_SEED) 9 | seed = 25252336454627188; 10 | #else 11 | seed = std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); 12 | seed ^= 5624630172374385489; 13 | seed ^= seed << 24, seed ^= seed >> 31, seed ^= seed << 35; 14 | #endif 15 | } 16 | } seed; 17 | } // namespace seed_impl 18 | u64& seed() { return seed_impl::seed.seed; } 19 | static const u64 FIXED_RANDOM = seed(); -------------------------------------------------------------------------------- /seq/longest_increasing_subsequence.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | std::pair longest_increasing_sequence(const vc& a) { 6 | const int n = len(a); 7 | vc dp(n, inf); 8 | vi lis_rank(n); 9 | _for (i, n) { 10 | int j = (strong ? LB(dp, a[i]) : UB(dp, a[i])); 11 | dp[j] = a[i]; 12 | lis_rank[i] = j + 1; 13 | } 14 | return {max(lis_rank), std::move(lis_rank)}; 15 | } 16 | template 17 | vi longest_increasing_sequence_id(const vc& a) { 18 | const int n = len(a); 19 | auto [m, d] = longest_increasing_sequence(a); 20 | vi I; 21 | I.reserve(m); 22 | T x = inf; 23 | _for_r (i, n) 24 | if (d[i] == m && (strong ? a[i] < x : a[i] <= x)) { 25 | I.eb(i); 26 | m--; 27 | x = a[i]; 28 | } 29 | reverse(I); 30 | return I; 31 | } -------------------------------------------------------------------------------- /string/count_subsequence.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ds/hashmap.hpp" 3 | 4 | template 5 | mint count_subsequence(auto&& s) { 6 | HashMap dp; 7 | mint ans = 1; 8 | foreach (x, s) { 9 | mint t = dp[x]; 10 | dp[x] = ans; 11 | ans += ans - t; 12 | } 13 | return ans - 1; 14 | } -------------------------------------------------------------------------------- /string/is_substring.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "string/zalgorithm.hpp" 3 | 4 | template 5 | bool is_substring(T s, const T& t) { 6 | int n = len(s), m = len(t); 7 | concat(s, t); 8 | auto z = zalgorithm(s); 9 | _for (i, n, n + m) 10 | if (z[i] >= n) 11 | return true; 12 | return false; 13 | } -------------------------------------------------------------------------------- /string/longest_common_subsequence.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | int longest_common_subsequence(auto&& a, auto&& b) { 5 | int n = len(b); 6 | vi d(n + 1); 7 | foreach (a, a) { 8 | _for_r (i, n) 9 | if (a == b[i]) 10 | chkmax(d[i + 1], d[i] + 1); 11 | _for (i, n) 12 | chkmax(d[i + 1], d[i]); 13 | } 14 | return d[n]; 15 | } 16 | vc longest_common_subsequence_result(auto&& a, auto&& b) { 17 | int n = len(a), m = len(b); 18 | VEC(int, d, n + 1, m + 1); 19 | _for (i, n) { 20 | d[i + 1] = d[i]; 21 | _for (j, m) { 22 | chkmax(d[i + 1][j + 1], d[i + 1][j]); 23 | if (a[i] == b[j]) 24 | chkmax(d[i + 1][j + 1], d[i][j] + 1); 25 | } 26 | } 27 | vc r; 28 | int i = n, j = m; 29 | while (d[i][j]) 30 | if (d[i][j] == d[i - 1][j]) 31 | i--; 32 | else if (d[i][j] == d[i][j - 1]) 33 | j--; 34 | else 35 | r.eb(--i, --j); 36 | reverse(r); 37 | return r; 38 | } -------------------------------------------------------------------------------- /string/split.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | vc split(std::string_view s, char sep = ' ') { 5 | vc ans{{}}; 6 | foreach (c, s) 7 | if (c == sep) 8 | ans.eb(); 9 | else 10 | ans.back().push_back(c); 11 | return ans; 12 | } 13 | 14 | vc split(std::string_view s, str seps) { 15 | vc ans{{}}; 16 | foreach (c, s) 17 | if (count(seps, c)) 18 | ans.eb(); 19 | else 20 | ans.back().push_back(c); 21 | return ans; 22 | } -------------------------------------------------------------------------------- /string/wildcard_pattern_matching.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "poly/middle_product.hpp" 3 | #include "random/base.hpp" 4 | 5 | vcb wildcard_pattern_matching(const str& s, const str& t, char wildcard = '?') { 6 | using mint = MMInt998244353; 7 | int shift = rnd(0, mint::mod()); 8 | int n = len(s), m = len(t); 9 | int mi = 1024; 10 | foreach (c, s) 11 | if (c != wildcard) 12 | chkmin(mi, c); 13 | foreach (c, t) 14 | if (c != wildcard) 15 | chkmin(mi, c); 16 | vc f1(n), g1(m), f2(n), g2(m), f3(n), g3(m); 17 | _for (i, n) 18 | f1[i] = s[i] == wildcard ? 0 : s[i] - mi + 1 + shift; 19 | _for (i, m) 20 | g1[i] = t[i] == wildcard ? 0 : t[i] - mi + 1 + shift; 21 | _for (i, n) 22 | f2[i] = f1[i] * f1[i], f3[i] = f2[i] * f1[i]; 23 | _for (i, m) 24 | g2[i] = g1[i] * g1[i], g3[i] = g2[i] * g1[i]; 25 | auto h1 = middle_product(f1, g3); 26 | auto h2 = middle_product(f2, g2); 27 | auto h3 = middle_product(f3, g1); 28 | vcb ans(n - m + 1); 29 | _for (i, n - m + 1) 30 | ans[i] = h1[i] == h2[i] + h2[i] - h3[i]; 31 | return ans; 32 | } -------------------------------------------------------------------------------- /string/zalgorithm.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | vi zalgorithm(const auto& s) { 5 | int n = len(s); 6 | if (n == 0) 7 | return {}; 8 | vi z(n); 9 | z[0] = 0; 10 | for (int i = 1, j = 0; i < n; i++) { 11 | int& k = z[i]; 12 | if (j + z[j] > i) 13 | k = Min(j + z[j] - i, z[i - j]); 14 | while (i + k < n && s[k] == s[i + k]) 15 | k++; 16 | if (j + z[j] < i + z[i]) 17 | j = i; 18 | } 19 | z[0] = n; 20 | return z; 21 | } -------------------------------------------------------------------------------- /test/aoj/ALDS1_10_C.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_10_C" 2 | 3 | #include "all.hpp" 4 | #include "string/longest_common_subsequence.hpp" 5 | 6 | void test(auto&& a, auto&& b) { 7 | int lcs = longest_common_subsequence(a, b); 8 | auto r = longest_common_subsequence_result(a, b); 9 | assert(len(r) == lcs); 10 | foreach (x, y, r) 11 | assert(a[x] == b[y]); 12 | _for (i, lcs - 1) { 13 | assert(r[i].first < r[i + 1].first); 14 | assert(r[i].second < r[i + 1].second); 15 | } 16 | } 17 | int main() { 18 | multipleTests([&] { 19 | dR(str, s, t); 20 | test(s, t); 21 | print(longest_common_subsequence(s, t)); 22 | }); 23 | return 0; 24 | } -------------------------------------------------------------------------------- /test/aoj/DPL_2_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_2_A" 2 | 3 | #include "all.hpp" 4 | #include "graph/minimum_hamiltonian_cycle.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | auto g = read_graph(n, m, 0); 9 | auto [cost, _] = minimum_hamiltonian_cycle(g); 10 | if (cost == inf) 11 | print(-1); 12 | else 13 | print(cost); 14 | return 0; 15 | } -------------------------------------------------------------------------------- /test/aoj/DSL_1_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_1_A" 2 | 3 | #include "all.hpp" 4 | #include "ds/unionfind.hpp" 5 | 6 | int main() { 7 | dR(int, n, q); 8 | UnionFind uf(n); 9 | _for (q) { 10 | dR(int, t, x, y); 11 | if (t == 0) 12 | uf.merge(x, y); 13 | else 14 | print(uf.same(x, y)); 15 | } 16 | return 0; 17 | } -------------------------------------------------------------------------------- /test/aoj/DSL_1_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_1_B" 2 | 3 | #include "all.hpp" 4 | #include "ds/weighted_unionfind.hpp" 5 | #include "monoid/add.hpp" 6 | 7 | int main() { 8 | dR(int, n, q); 9 | Weighted_UnionFind> wuf(n); 10 | _for (q) { 11 | dR(int, t, x, y); 12 | if (t == 0) { 13 | dR(int, z); 14 | wuf.merge(x, y, z); 15 | } 16 | else { 17 | auto [x0, vx] = wuf[x]; 18 | auto [y0, vy] = wuf[y]; 19 | if (x0 != y0) 20 | print('?'); 21 | else 22 | print(vy - vx); 23 | } 24 | } 25 | return 0; 26 | } -------------------------------------------------------------------------------- /test/aoj/DSL_2_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_A" 2 | 3 | #include "all.hpp" 4 | #include "ds/segtree.hpp" 5 | #include "monoid/min.hpp" 6 | 7 | int main() { 8 | dR(int, n, q); 9 | SegTree> st(n, [&](int) { return INT_MAX; }); 10 | _for (q) { 11 | dR(int, t, x, y); 12 | if (t == 0) { 13 | st.set(x, y); 14 | } 15 | else { 16 | print(st.prod(x, y + 1)); 17 | } 18 | } 19 | return 0; 20 | } -------------------------------------------------------------------------------- /test/aoj/DSL_2_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_B" 2 | 3 | #include "all.hpp" 4 | #include "ds/segtree.hpp" 5 | #include "monoid/add.hpp" 6 | 7 | int main() { 8 | dR(int, n, q); 9 | SegTree> st(n); 10 | _for (q) { 11 | dR(int, t, x, y), x--; 12 | if (t == 0) { 13 | st.multiply(x, y); 14 | } 15 | else { 16 | print(st.prod(x, y)); 17 | } 18 | } 19 | return 0; 20 | } -------------------------------------------------------------------------------- /test/aoj/DSL_2_C.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_C" 2 | 3 | #include "all.hpp" 4 | #include "ds/kdtree.hpp" 5 | 6 | int main() { 7 | dR(int, n); 8 | vi X(n), Y(n); 9 | io.zipread(X, Y); 10 | KDTree tree(X, Y); 11 | dR(int, q); 12 | _for (q) { 13 | dR(int, xl, xr, yl, yr), xr++, yr++; 14 | auto I = tree.collect_rect(xl, xr, yl, yr); 15 | sort(I); 16 | foreach (i, I) 17 | print(i); 18 | print(); 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /test/aoj/DSL_2_D.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_D" 2 | 3 | #include "all.hpp" 4 | #include "ds/dual_segtree.hpp" 5 | #include "monoid/assign.hpp" 6 | 7 | int main() { 8 | dR(int, n, q); 9 | Dual_SegTree> st(n); 10 | _for (q) { 11 | dR(int, t, x); 12 | if (t == 0) { 13 | dR(int, y, z); 14 | st.apply(x, y + 1, z); 15 | } 16 | else { 17 | print(st.get(x)); 18 | } 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /test/aoj/DSL_2_E.ft.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_E" 2 | 3 | #include "all.hpp" 4 | #include "ds/range_add_range_sum.hpp" 5 | #include "monoid/add.hpp" 6 | 7 | int main() { 8 | dR(int, n, q); 9 | Range_Add_Range_Sum> ft(n); 10 | _for (q) { 11 | dR(int, t, x), x--; 12 | if (t == 0) { 13 | dR(int, y, z); 14 | ft.apply(x, y, z); 15 | } 16 | else { 17 | print(ft.prod(x, x + 1)); 18 | } 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /test/aoj/DSL_2_E.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_E" 2 | 3 | #include "all.hpp" 4 | #include "ds/dual_segtree.hpp" 5 | #include "monoid/add.hpp" 6 | 7 | int main() { 8 | dR(int, n, q); 9 | Dual_SegTree> st(n); 10 | _for (q) { 11 | dR(int, t, x), x--; 12 | if (t == 0) { 13 | dR(int, y, z); 14 | st.apply(x, y, z); 15 | } 16 | else { 17 | print(st.get(x)); 18 | } 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /test/aoj/DSL_2_F.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_F" 2 | 3 | #include "all.hpp" 4 | #include "ds/lazy_segtree.hpp" 5 | #include "acted_monoid/min_assign.hpp" 6 | 7 | int main() { 8 | dR(int, n, q); 9 | Lazy_SegTree> st(n, [&](int) { return INT_MAX; }); 10 | _for (q) { 11 | dR(int, t, l, r), r++; 12 | if (t == 0) { 13 | dR(int, x); 14 | st.apply(l, r, x); 15 | } 16 | else { 17 | print(st.prod(l, r)); 18 | } 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /test/aoj/DSL_2_G.ft.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_G" 2 | 3 | #include "all.hpp" 4 | #include "ds/range_add_range_sum.hpp" 5 | #include "monoid/add.hpp" 6 | 7 | int main() { 8 | dR(int, n, q); 9 | Range_Add_Range_Sum> ft(n); 10 | _for (q) { 11 | dR(int, t, l, r), l--; 12 | if (t == 0) { 13 | dR(int, x); 14 | ft.apply(l, r, x); 15 | } 16 | else { 17 | print(ft.prod(l, r)); 18 | } 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /test/aoj/DSL_2_G.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_G" 2 | 3 | #include "all.hpp" 4 | #include "ds/lazy_segtree.hpp" 5 | #include "acted_monoid/sum_add.hpp" 6 | 7 | int main() { 8 | dR(int, n, q); 9 | Lazy_SegTree> st(n); 10 | _for (q) { 11 | dR(int, t, l, r), l--; 12 | if (t == 0) { 13 | dR(int, x); 14 | st.apply(l, r, x); 15 | } 16 | else { 17 | print(st.prod(l, r)); 18 | } 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /test/aoj/DSL_2_H.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_H" 2 | 3 | #include "all.hpp" 4 | #include "ds/lazy_segtree.hpp" 5 | #include "acted_monoid/min_add.hpp" 6 | 7 | int main() { 8 | dR(int, n, q); 9 | Lazy_SegTree> st(n, [&](int) { return 0; }); 10 | _for (q) { 11 | dR(int, t, l, r), r++; 12 | if (t == 0) { 13 | dR(int, x); 14 | st.apply(l, r, x); 15 | } 16 | else { 17 | print(st.prod(l, r)); 18 | } 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /test/aoj/DSL_2_I.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_I" 2 | 3 | #include "all.hpp" 4 | #include "ds/lazy_segtree.hpp" 5 | #include "acted_monoid/sum_assign.hpp" 6 | 7 | int main() { 8 | dR(int, n, q); 9 | Lazy_SegTree> st(n); 10 | _for (q) { 11 | dR(int, t, l, r), r++; 12 | if (t == 0) { 13 | dR(int, x); 14 | st.apply(l, r, x); 15 | } 16 | else { 17 | print(st.prod(l, r)); 18 | } 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /test/aoj/DSL_3_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_3_A" 2 | 3 | #include "all.hpp" 4 | #include "ds/swag.hpp" 5 | #include "monoid/add.hpp" 6 | 7 | int main() { 8 | dR(int, n, s); 9 | dRV(int, a, n); 10 | SWAG> swag; 11 | int ans = inf; 12 | foreach (x, a) { 13 | swag.push(x); 14 | while (swag.prod() >= s) { 15 | chkmin(ans, len(swag)); 16 | swag.pop(); 17 | } 18 | } 19 | print(ans == inf ? 0 : ans); 20 | return 0; 21 | } -------------------------------------------------------------------------------- /test/aoj/DSL_4_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_4_A" 2 | 3 | #include "all.hpp" 4 | #include "ds/rectangle_union.hpp" 5 | 6 | int main() { 7 | dR(int, n); 8 | Rectangle_Union ru; 9 | _for (n) { 10 | dR(int, xl, yl, xr, yr); 11 | ru.add(xl, xr, yl, yr); 12 | } 13 | print(ru.calc()); 14 | return 0; 15 | } -------------------------------------------------------------------------------- /test/aoj/GRL_1_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_A" 2 | 3 | #include "all.hpp" 4 | #include "graph/dijkstra.hpp" 5 | 6 | int main() { 7 | dR(int, n, m, s); 8 | auto g = read_graph(n, m, 0); 9 | auto [dis, par] = dijkstra(g, s); 10 | _for (i, n) { 11 | if (dis[i] == inf) 12 | print("INF"); 13 | else 14 | print(dis[i]); 15 | } 16 | return 0; 17 | } -------------------------------------------------------------------------------- /test/aoj/GRL_1_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_B" 2 | 3 | #include "all.hpp" 4 | #include "graph/bellmanford.hpp" 5 | 6 | int main() { 7 | dR(int, n, m, s); 8 | auto g = read_graph(n, m, 0); 9 | auto [dis, par] = BellmanFord(g, s); 10 | if (min(dis) == -inf) { 11 | print("NEGATIVE CYCLE"); 12 | return 0; 13 | } 14 | _for (i, n) { 15 | if (dis[i] == inf) 16 | print("INF"); 17 | else 18 | print(dis[i]); 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /test/aoj/GRL_1_C.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_C" 2 | 3 | #include "all.hpp" 4 | #include "graph/floyd.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | auto g = read_graph(n, m, 0); 9 | auto dis = floyd(g); 10 | _for (i, n) 11 | if (dis[i][i] < 0) { 12 | print("NEGATIVE CYCLE"); 13 | return 0; 14 | } 15 | _for (i, n) { 16 | _for (j, n) { 17 | if (j) 18 | io.write(' '); 19 | if (dis[i][j] == inf) 20 | io.write("INF"); 21 | else 22 | io.write(dis[i][j]); 23 | } 24 | print(); 25 | } 26 | return 0; 27 | } -------------------------------------------------------------------------------- /test/aoj/GRL_2_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_2_A" 2 | 3 | #include "all.hpp" 4 | #include "graph/kruskal.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | auto g = read_graph(n, m, 0); 9 | print(kruskal(g).cost); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /test/aoj/GRL_2_B.pool.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_2_B" 2 | 3 | #include "all.hpp" 4 | #include "graph/minimum_cost_arborescence.hpp" 5 | 6 | int main() { 7 | dR(int, n, m, r); 8 | auto g = read_graph(n, m, 0); 9 | auto [cost, I] = MinimumCostArborescence(g, r); 10 | print(cost); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /test/aoj/GRL_2_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_2_B" 2 | 3 | #include "all.hpp" 4 | #include "graph/minimum_cost_arborescence.hpp" 5 | 6 | int main() { 7 | dR(int, n, m, r); 8 | auto g = read_graph(n, m, 0); 9 | auto [cost, I] = MinimumCostArborescence<1500>(g, r); 10 | print(cost); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /test/aoj/GRL_3_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_3_A" 2 | 3 | #include "all.hpp" 4 | #include "graph/block_cut_tree.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | auto g = read_graph(n, m, 0); 9 | auto bct = block_cut_tree(g); 10 | _for (i, n) 11 | if (bct.deg(i) > 1) 12 | print(i); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /test/aoj/GRL_3_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_3_B" 2 | 3 | #include "all.hpp" 4 | #include "graph/two_edge_component.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | auto g = read_graph(n, m, 0); 9 | auto [bcc, comp] = two_edge_component(g); 10 | vc ans; 11 | foreach (e, g.edges) 12 | if (comp[e.from] != comp[e.to]) { 13 | if (e.from < e.to) 14 | ans.eb(e.from, e.to); 15 | else 16 | ans.eb(e.to, e.from); 17 | } 18 | sort(ans); 19 | foreach (x, ans) 20 | print(x); 21 | return 0; 22 | } -------------------------------------------------------------------------------- /test/aoj/GRL_3_C.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_3_C" 2 | 3 | #include "all.hpp" 4 | #include "graph/strongly_connected_component.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | auto g = read_graph(n, m, 0); 9 | auto [scc, comp] = strongly_connected_component(g); 10 | dR(int, q); 11 | _for (q) { 12 | dR(int, x, y); 13 | print(comp[x] == comp[y]); 14 | } 15 | return 0; 16 | } -------------------------------------------------------------------------------- /test/aoj/GRL_4_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_4_A" 2 | 3 | #include "all.hpp" 4 | #include "graph/find_cycle.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | auto g = read_graph(n, m, 0); 9 | auto cycle = find_cycle(g); 10 | print(!cycle.vs.empty()); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /test/aoj/GRL_4_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_4_B" 2 | 3 | #include "all.hpp" 4 | #include "graph/topological_sort.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | auto g = read_graph(n, m, 0); 9 | auto V = *toposort(g); 10 | io.displayArray(V, '\n'); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /test/aoj/GRL_5_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_A" 2 | 3 | #include "all.hpp" 4 | #include "graph/utility.hpp" 5 | 6 | int main() { 7 | dR(int, n); 8 | auto g = read_tree(n, 0); 9 | print(diameter(g).diam); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /test/aoj/GRL_5_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_B" 2 | 3 | #include "all.hpp" 4 | #include "graph/utility.hpp" 5 | 6 | int main() { 7 | dR(int, n); 8 | auto g = read_tree(n, 0); 9 | auto [d1, _0] = bfs01(g, 0); 10 | int u = max_element(d1) - d1.begin(); 11 | auto [d2, _1] = bfs01(g, u); 12 | int v = max_element(d2) - d2.begin(); 13 | auto [d3, _2] = bfs01(g, v); 14 | _for (i, n) 15 | print(max(d2[i], d3[i])); 16 | return 0; 17 | } -------------------------------------------------------------------------------- /test/aoj/GRL_5_C.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_C" 2 | 3 | #include "all.hpp" 4 | #include "graph/tree.hpp" 5 | 6 | int main() { 7 | dR(int, n); 8 | Graph g(n); 9 | _for (i, n) { 10 | dR(int, t); 11 | _for (t) { 12 | dR(int, v); 13 | g.add(i, v); 14 | } 15 | } 16 | g.build(); 17 | Tree tree(g); 18 | dR(int, q); 19 | _for (q) { 20 | dR(int, x, y); 21 | print(tree.lca(x, y)); 22 | } 23 | return 0; 24 | } -------------------------------------------------------------------------------- /test/aoj/GRL_5_D.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_D" 2 | 3 | #include "all.hpp" 4 | #include "graph/tree.hpp" 5 | #include "graph/tree_monoid.hpp" 6 | #include "monoid/add.hpp" 7 | 8 | int main() { 9 | dR(int, n); 10 | Graph g(n); 11 | _for (i, n) { 12 | dR(int, t); 13 | _for (t) { 14 | dR(int, v); 15 | g.add(i, v); 16 | } 17 | } 18 | g.build(); 19 | Tree tree(g); 20 | Tree_Monoid, true> st(tree); 21 | dR(int, q); 22 | _for (q) { 23 | dR(int, t); 24 | if (t == 0) { 25 | dR(int, u, w); 26 | st.multiply(tree.v_to_e(u), w); 27 | } 28 | else { 29 | dR(int, u); 30 | print(st.prod_path(0, u)); 31 | } 32 | } 33 | return 0; 34 | } -------------------------------------------------------------------------------- /test/aoj/GRL_5_E.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_E" 2 | 3 | #include "all.hpp" 4 | #include "graph/tree.hpp" 5 | #include "graph/lazy_tree_monoid.hpp" 6 | #include "acted_monoid/sum_add.hpp" 7 | 8 | int main() { 9 | dR(int, n); 10 | Graph g(n); 11 | _for (i, n) { 12 | dR(int, t); 13 | _for (t) { 14 | dR(int, v); 15 | g.add(i, v); 16 | } 17 | } 18 | g.build(); 19 | Tree tree(g); 20 | Lazy_Tree_Monoid, true> st(tree); 21 | dR(int, q); 22 | _for (q) { 23 | dR(int, t); 24 | if (t == 0) { 25 | dR(int, u, w); 26 | st.apply_path(0, u, w); 27 | } 28 | else { 29 | dR(int, u); 30 | print(st.prod_path(0, u)); 31 | } 32 | } 33 | return 0; 34 | } -------------------------------------------------------------------------------- /test/aoj/GRL_6_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_A" 2 | 3 | #include "all.hpp" 4 | #include "flow/maxflow.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | MaxFlow mf(n, 0, n - 1); 9 | _for (m) { 10 | dR(int, u, v, c); 11 | mf.add(u, v, c); 12 | } 13 | mf.build(); 14 | writeln(mf.flow()); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /test/aoj/ITP1_3_D.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_3_D" 2 | 3 | #include "all.hpp" 4 | #include "math/divisors.hpp" 5 | 6 | int main() { 7 | dR(int, a, b, c); 8 | int ans = 0; 9 | foreach (d, divisors(u32(c))) 10 | if (a <= d && d <= b) 11 | ans++; 12 | print(ans); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /test/aoj/ITP1_9_A.io2.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_9_A" 2 | 3 | #include "all2.hpp" 4 | #include "string/split.hpp" 5 | 6 | int main() { 7 | dR(str, t); 8 | int ans = 0; 9 | str line; 10 | while (io.readline(line)) { 11 | foreach (s, split(line)) { 12 | transform(s, s.begin(), ::tolower); 13 | if (s == t) 14 | ans++; 15 | } 16 | } 17 | print(ans); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /test/aoj/ITP1_9_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_9_A" 2 | 3 | #include "all.hpp" 4 | #include "string/split.hpp" 5 | 6 | int main() { 7 | dR(str, t); 8 | int ans = 0; 9 | str line; 10 | loop { 11 | str line; 12 | io.readline(line); 13 | if (line == "END_OF_TEXT") 14 | break; 15 | foreach (s, split(line)) { 16 | transform(s, s.begin(), ::tolower); 17 | if (s == t) 18 | ans++; 19 | } 20 | } 21 | print(ans); 22 | return 0; 23 | } -------------------------------------------------------------------------------- /test/aoj/NTL_1_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_1_A" 2 | 3 | #include "all.hpp" 4 | #include "math/factorize.hpp" 5 | 6 | int main() { 7 | dR(u32, n); 8 | writeln(n, ": ", factorize(n)); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /test/aoj/NTL_1_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_1_B" 2 | 3 | #include "all.hpp" 4 | #include "modint/montgomery.hpp" 5 | 6 | using mint = MMInt1000000007; 7 | int main() { 8 | dR(u32, m, n); 9 | print(power(m, n)); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /test/aoj/NTL_1_C.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_1_C" 2 | 3 | #include "all.hpp" 4 | #include "math/lcm.hpp" 5 | 6 | int main() { 7 | dR(int, n); 8 | dRV(int, a, n); 9 | print(lcm(a)); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /test/aoj/NTL_1_D.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_1_D" 2 | 3 | #include "all.hpp" 4 | #include "math/euler_phi.hpp" 5 | 6 | int main() { 7 | dR(u32, n); 8 | print(euler_phi(n)); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /test/aoj/NTL_1_E.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_1_E" 2 | 3 | #include "all.hpp" 4 | #include "math/exgcd.hpp" 5 | 6 | int main() { 7 | dR(int, a, b); 8 | auto [x, y, d] = exgcd(a, b); 9 | print(x, y); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /test/aoj/NTL_2_A.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_2_A" 2 | 3 | #include "all.hpp" 4 | #include "math/bigint.hpp" 5 | 6 | int main() { 7 | dR(bigint, a, b); 8 | print(a + b); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /test/aoj/NTL_2_B.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_2_B" 2 | 3 | #include "all.hpp" 4 | #include "math/bigint.hpp" 5 | 6 | int main() { 7 | dR(bigint, a, b); 8 | print(a - b); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /test/aoj/NTL_2_C.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_2_C" 2 | 3 | #include "all.hpp" 4 | #include "math/bigint.hpp" 5 | 6 | int main() { 7 | dR(bigint, a, b); 8 | print(a * b); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /test/aoj/NTL_2_D.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_2_D" 2 | 3 | #include "all.hpp" 4 | #include "math/bigint.hpp" 5 | 6 | int main() { 7 | dR(bigint, a, b); 8 | print(a / b); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /test/aoj/NTL_2_E.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_2_E" 2 | 3 | #include "all.hpp" 4 | #include "math/bigint.hpp" 5 | 6 | int main() { 7 | dR(bigint, a, b); 8 | print(a % b); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /test/aoj/NTL_2_F.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=NTL_2_F" 2 | 3 | #include "all.hpp" 4 | #include "math/bigint.hpp" 5 | 6 | int main() { 7 | dR(bigint, a, b); 8 | print(a * b); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /test/atcoder/abc217_e.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/abc217/tasks/abc217_e" 2 | 3 | #include "all.hpp" 4 | #include "ds/sortable_array.hpp" 5 | 6 | int main() { 7 | dR(int, n); 8 | Sortable_Array<2 * ten(7)> sa(inf, vi(n)); 9 | int l = 0, r = 0; 10 | _for (n) { 11 | dR(int, t); 12 | if (t == 1) { 13 | dR(int, x); 14 | sa.set(r++, x); 15 | } 16 | else if (t == 2) { 17 | print(sa.get(l++)); 18 | } 19 | else { 20 | sa.sort(l, r); 21 | } 22 | } 23 | return 0; 24 | } -------------------------------------------------------------------------------- /test/atcoder/abc237_g.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/abc237/tasks/abc237_g" 2 | 3 | #include "all.hpp" 4 | #include "ds/sortable_array.hpp" 5 | 6 | int main() { 7 | dR(int, n, q, x); 8 | dRV(int, a, n); 9 | Sortable_Array sa(n + 1, a); 10 | _for (q) { 11 | dR(int, t, l, r), l--; 12 | sa.sort(l, r, t == 2); 13 | } 14 | a = sa.get_all(); 15 | print(find(a, x) - a.begin() + 1); 16 | return 0; 17 | } -------------------------------------------------------------------------------- /test/atcoder/abc266_f.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/abc266/tasks/abc266_f" 2 | 3 | #include "all.hpp" 4 | #include "graph/unicyclic.hpp" 5 | 6 | int main() { 7 | dR(int, n); 8 | auto g = read_graph(n, n); 9 | UnicyclicGraph ug(g); 10 | auto tree = ug.build().second; 11 | dR(int, q); 12 | _for (q) { 13 | dR(int, u, v), u--, v--; 14 | int u0 = tree.lca(u, ug.bottom), v0 = tree.lca(v, ug.bottom); 15 | Yes(u0 == v0); 16 | } 17 | return 0; 18 | } -------------------------------------------------------------------------------- /test/atcoder/abc268_h.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/abc268/tasks/abc268_Ex" 2 | 3 | #include "all.hpp" 4 | #include "string/trie.hpp" 5 | 6 | int main() { 7 | dR(str, s); 8 | dR(int, n); 9 | Trie<26, decltype([](char c) { return c - 'a'; })> trie; 10 | _for (n) { 11 | dR(str, s); 12 | trie.insert(s); 13 | } 14 | trie.calc_suffix_link(true); 15 | auto cnt = trie.calc_count(); 16 | int ans = 0, u = 1; 17 | foreach (c, s) { 18 | int x = c - 'a'; 19 | u = trie.child[u][x]; 20 | if (cnt[u]) { 21 | ans++; 22 | u = 1; 23 | } 24 | } 25 | print(ans); 26 | return 0; 27 | } -------------------------------------------------------------------------------- /test/atcoder/abc294_g.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/abc294/tasks/abc294_g" 2 | 3 | #include "all.hpp" 4 | #include "graph/tree.hpp" 5 | #include "graph/tree_abelgroup.hpp" 6 | #include "monoid/add.hpp" 7 | 8 | int main() { 9 | dR(int, n); 10 | auto g = read_tree(n); 11 | Tree tree(g); 12 | Tree_AbelGroup, true, true, false> seg(tree, [&](int i) { return g.edges[i].cost; }); 13 | dR(int, q); 14 | _for (q) { 15 | dR(int, t, x, y); 16 | if (t == 1) { 17 | x--; 18 | seg.multiply(x, y - g.edges[x].cost); 19 | g.edges[x].cost = y; 20 | } 21 | else { 22 | x--, y--; 23 | print(seg.prod_path(x, y)); 24 | } 25 | } 26 | return 0; 27 | } -------------------------------------------------------------------------------- /test/atcoder/abc318_g.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/abc318/tasks/abc318_g" 2 | 3 | #include "all.hpp" 4 | #include "flow/maxflow.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | dR(int, a, b, c), a--, b--, c--; 9 | 10 | int s = n * 2, t = n * 2 + 1; 11 | MaxFlow mf(n * 2 + 2, s, t); 12 | 13 | _for (i, n) 14 | mf.add(i, i + n, 1); 15 | mf.add(b, b + n, 1); 16 | 17 | mf.add(s, b, 2); 18 | mf.add(a + n, t, 1); 19 | mf.add(c + n, t, 1); 20 | 21 | _for (m) { 22 | dR(int, u, v), u--, v--; 23 | mf.add(u + n, v, 1); 24 | mf.add(v + n, u, 1); 25 | } 26 | mf.build(); 27 | Yes(mf.flow() == 2); 28 | return 0; 29 | } -------------------------------------------------------------------------------- /test/atcoder/abc319_d.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/abc319/tasks/abc319_d" 2 | 3 | #include "all.hpp" 4 | #include "math/binary_search.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | dRV(int, a, n); 9 | 10 | auto check = [&](i64 x) { 11 | int c = 1; 12 | i64 s = -1; 13 | _for (i, n) { 14 | if (s + a[i] + 1 > x) { 15 | c++; 16 | s = -1; 17 | } 18 | s += a[i] + 1; 19 | } 20 | return c <= m; 21 | }; 22 | print(bsearch(check, inf, max(a) - 1)); 23 | return 0; 24 | } -------------------------------------------------------------------------------- /test/atcoder/abc324_f.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/abc324/tasks/abc324_f" 2 | 3 | #include "all.hpp" 4 | #include "graph/base.hpp" 5 | #include "math/binary_search.hpp" 6 | 7 | int main() { 8 | dR(int, n, m); 9 | Graph g(n, m); 10 | vi B(m), C(m); 11 | _for (i, m) { 12 | dR(int, u, v), u--, v--; 13 | io.read(B[i], C[i]); 14 | g.add(u, v); 15 | } 16 | g.build(); 17 | auto check = [&](auto mi) { 18 | vc dp(n, -inf); 19 | dp[0] = 0; 20 | _for (u, n) 21 | foreach (v, g[u]) 22 | chkmax(dp[v], dp[u] + B[v.id] - mi * C[v.id]); 23 | return dp[n - 1] >= 0; 24 | }; 25 | io.setprec(16); 26 | print(bsearch(check, 0, inf)); 27 | return 0; 28 | } -------------------------------------------------------------------------------- /test/atcoder/abc325_e.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/abc325/tasks/abc325_e" 2 | 3 | #include "all.hpp" 4 | #include "graph/dijkstra.hpp" 5 | 6 | int main() { 7 | dR(int, n, a, b, c); 8 | Graph g(n * 2); 9 | _for (i, n) 10 | _for (j, n) { 11 | dR(i64, x); 12 | g.add(i, j, x * a); 13 | g.add(i + n, j + n, x * b + c); 14 | } 15 | _for (i, n) 16 | g.add(i, i + n, 0); 17 | g.build(); 18 | print(dijkstra_dense(g).dis.back()); 19 | return 0; 20 | } -------------------------------------------------------------------------------- /test/atcoder/abc337_c.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/abc337/tasks/abc337_c" 2 | 3 | #include "all.hpp" 4 | #include "utility/cache.hpp" 5 | 6 | int main() { 7 | dR(int, n); 8 | dRV(int, a, n); 9 | auto get = use_cache([&](auto&& self, int u) -> int { 10 | if (a[u] == -1) 11 | return 0; 12 | return self(a[u] - 1) + 1; 13 | }); 14 | vi ans(n); 15 | _for (i, n) 16 | ans[get(i)] = i + 1; 17 | print(ans); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /test/atcoder/abc362_f.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/abc362/tasks/abc362_f" 2 | 3 | #include "all.hpp" 4 | #include "graph/find_centroids.hpp" 5 | 6 | int main() { 7 | dR(int, n); 8 | auto g = read_tree(n); 9 | auto [c, _] = find_centroids(g); 10 | vi V; 11 | auto dfs = [&](auto&& dfs, int u, int f) -> void { 12 | V.eb(u); 13 | foreach (v, g[u]) 14 | if (v != f) 15 | dfs(dfs, v, u); 16 | }; 17 | foreach (u, g[c]) 18 | dfs(dfs, u, c); 19 | V.eb(c); 20 | _for (i, n / 2) 21 | print(V[i] + 1, V[i + n / 2] + 1); 22 | return 0; 23 | } -------------------------------------------------------------------------------- /test/atcoder/abc362_g.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/abc362/tasks/abc362_g" 2 | 3 | #include "all.hpp" 4 | #include "string/suffix_array.hpp" 5 | 6 | int main() { 7 | dR(str, S); 8 | dR(int, n); 9 | S += '$'; 10 | vi cut{0}; 11 | cut.eb(len(S)); 12 | _for (n) { 13 | dR(str, t); 14 | S += t; 15 | cut.eb(len(S)); 16 | } 17 | Suffix_Array SA(S); 18 | SA.build_lcp(); 19 | vi a(len(S)); 20 | _for (i, cut[1]) 21 | a[SA.isa[i]] = 1; 22 | auto Ac = cumsum(a); 23 | _for (i, n) { 24 | int l = cut[i + 1], r = cut[i + 2]; 25 | auto [x, y] = SA.lcp_range(l, r - l); 26 | print(Ac[y] - Ac[x]); 27 | } 28 | return 0; 29 | } -------------------------------------------------------------------------------- /test/atcoder/arc157_a.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/arc157/tasks/arc157_a" 2 | 3 | #include "all.hpp" 4 | #include "graph/euler_walk.hpp" 5 | 6 | int main() { 7 | dR(int, n, a, b, c, d); 8 | Graph g(2); 9 | _for (a) 10 | g.add(0, 0); 11 | _for (b) 12 | g.add(0, 1); 13 | _for (c) 14 | g.add(1, 0); 15 | _for (d) 16 | g.add(1, 1); 17 | g.build(); 18 | Yes(!euler_walk(g).vs.empty()); 19 | return 0; 20 | } -------------------------------------------------------------------------------- /test/atcoder/past202004_n.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/past202004-open/tasks/past202004_n" 2 | 3 | #include "all.hpp" 4 | #include "ds/dual_kdtree_monoid.hpp" 5 | #include "monoid/add.hpp" 6 | 7 | int main() { 8 | dR(int, n, q); 9 | using T = std::tuple; 10 | dRV(T, a, n); 11 | vi X(q), Y(q); 12 | io.zipread(X, Y); 13 | Dual_KDTree_Monoid> tree(X, Y); 14 | foreach (x, y, d, c, a) 15 | tree.apply(x, x + d + 1, y, y + d + 1, c); 16 | _for (i, q) 17 | print(tree.get(i)); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /test/atcoder/past202004_o.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/past202004-open/tasks/past202004_o" 2 | 3 | #include "all.hpp" 4 | #include "graph/static_tree_monoid.hpp" 5 | #include "graph/tree.hpp" 6 | #include "graph/kruskal.hpp" 7 | #include "monoid/max.hpp" 8 | 9 | int main() { 10 | dR(int, n, m); 11 | auto g = read_graph(n, m); 12 | auto [cost, in, mst] = kruskal(g); 13 | Tree tree(mst); 14 | Static_Tree_Monoid, true> st(tree, [&](int i) { return mst.edges[i].cost; }); 15 | _for (i, m) { 16 | if (in[i]) { 17 | print(cost); 18 | } 19 | else { 20 | auto&& e = g.edges[i]; 21 | print(cost + e.cost - st.prod_path(e.from, e.to)); 22 | } 23 | } 24 | return 0; 25 | } -------------------------------------------------------------------------------- /test/atcoder/past202005_m.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/past202005-open/tasks/past202005_m" 2 | 3 | #include "all.hpp" 4 | #include "graph/bfs01.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | auto g = read_graph(n, m); 9 | dR(int, s, K), s--; 10 | dRV(int, a, K); 11 | foreach (a, a) 12 | a--; 13 | vvi dis(K); 14 | _for (i, K) 15 | dis[i] = bfs01(g, a[i]).dis; 16 | VECI(dp, 1 << K, K, inf); 17 | _for (i, K) 18 | dp[1 << i][i] = dis[i][s]; 19 | _for (s, 1 << K) { 20 | _for (i, K) { 21 | if (dp[s][i] == inf) 22 | continue; 23 | _for (j, K) 24 | if (!(s >> j & 1)) 25 | chkmin(dp[s | 1 << j][j], dp[s][i] + dis[i][a[j]]); 26 | } 27 | } 28 | print(min(dp.back())); 29 | return 0; 30 | } -------------------------------------------------------------------------------- /test/atcoder/past202005_n.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/past202005-open/tasks/past202005_n" 2 | 3 | #include "all.hpp" 4 | #include "ds/sortable_array.hpp" 5 | 6 | int main() { 7 | dR(int, n, q); 8 | vi a(n); 9 | iota(all(a), 1); 10 | Sortable_Array<2 * ten(7)> sa(n + 1, a); 11 | _for (q) { 12 | dR(int, t, x, y); 13 | if (t == 1) { 14 | x--; 15 | auto vx = sa.get(x), vy = sa.get(x + 1); 16 | sa.set(x, vy); 17 | sa.set(x + 1, vx); 18 | } 19 | else { 20 | x--; 21 | sa.sort(x, y); 22 | } 23 | } 24 | print(sa.get_all()); 25 | return 0; 26 | } -------------------------------------------------------------------------------- /test/atcoder/past202010_f.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/past202010-open/tasks/past202010_f" 2 | 3 | #include "all.hpp" 4 | #include "ds/counter.hpp" 5 | 6 | int main() { 7 | dR(int, n, k), k--; 8 | dRV(str, a, n); 9 | auto C = Counter(a).most_common(); 10 | vc K(len(C)); 11 | vi V(len(C)); 12 | _for (i, len(C)) { 13 | K[i] = C[i].first; 14 | V[i] = C[i].second; 15 | } 16 | if (Counter(V)[V[k]] == 1) { 17 | print(K[k]); 18 | } 19 | else { 20 | print("AMBIGUOUS"); 21 | } 22 | return 0; 23 | } -------------------------------------------------------------------------------- /test/atcoder/past202010_h.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/past202010-open/tasks/past202010_h" 2 | 3 | #include "all.hpp" 4 | #include "ds/counter.hpp" 5 | 6 | int main() { 7 | dR(int, n, m, k); 8 | dRV(str, s, n); 9 | _for_r (t, 1, min(n, m) + 1) { 10 | _for (i, n - t + 1) { 11 | _for (j, m - t + 1) { 12 | Counter c; 13 | _for (x, t) 14 | _for (y, t) 15 | c[s[i + x][j + y]]++; 16 | if (t * t - c.most_common()[0].second <= k) { 17 | print(t); 18 | return 0; 19 | } 20 | } 21 | } 22 | } 23 | return 0; 24 | } -------------------------------------------------------------------------------- /test/atcoder/past202010_m.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://atcoder.jp/contests/past202010-open/tasks/past202010_m" 2 | 3 | #include "all.hpp" 4 | #include "graph/tree.hpp" 5 | #include "graph/dual_tree_monoid.hpp" 6 | #include "monoid/assign.hpp" 7 | 8 | int main() { 9 | dR(int, n, m); 10 | auto g = read_tree(n); 11 | Tree tree(g); 12 | Dual_Tree_Monoid, true> seg(tree); 13 | _for (m) { 14 | dR(int, x, y, z), x--, y--; 15 | seg.apply_path(x, y, z); 16 | } 17 | io.displayArray(seg.get_all(), '\n'); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /test/custom/all_inverse.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/aplusb" 2 | 3 | #include "all.hpp" 4 | #include "random/base.hpp" 5 | #include "modint/all_inverse.hpp" 6 | #include "modint/montgomery.hpp" 7 | #include "modint/mint61.hpp" 8 | #include "modint/barrett.hpp" 9 | 10 | template 11 | void test0() { 12 | vi N{1, 2, 3, 4, 5, 100000}; 13 | foreach (n, N) { 14 | vc a(n); 15 | _for (i, n) 16 | a[i] = rnd(1, mint::mod()); 17 | auto b = all_inverse(a); 18 | _for (i, n) 19 | assert(a[i] * b[i] == 1); 20 | } 21 | } 22 | void test() { 23 | test0(); 24 | test0(); 25 | test0(); 26 | test0>(); 27 | { 28 | SetBMod(u32, 998244353); 29 | test0(); 30 | } 31 | { 32 | SetBMod(u64, 909090909090909091); 33 | test0(); 34 | } 35 | } 36 | int main() { 37 | test(); 38 | 39 | dR(int, a, b); 40 | print(a + b); 41 | return 0; 42 | } -------------------------------------------------------------------------------- /test/custom/bellmanford.1.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/aplusb" 2 | 3 | #include "all.hpp" 4 | #include "graph/bellmanford.hpp" 5 | 6 | void test() { 7 | const int n = 4000; 8 | Graph g(n); 9 | _for (i, n - 2) 10 | g.add(i, i + 1, -100); 11 | g.add(n - 2, n - 1, 100); 12 | g.add(n - 1, 0, -100); 13 | g.build(); 14 | auto dis = BellmanFord(g).dis; 15 | assert(count(dis, -inf) == n); 16 | } 17 | int main() { 18 | test(); 19 | 20 | dR(int, a, b); 21 | print(a + b); 22 | return 0; 23 | } -------------------------------------------------------------------------------- /test/custom/convolution_square.avx2.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/aplusb" 2 | 3 | #include "all.hpp" 4 | #include "poly/ntt_avx2.hpp" 5 | #include "poly/convolution.hpp" 6 | #include "poly/convolution_square.hpp" 7 | #include "random/base.hpp" 8 | 9 | template 10 | void test0() { 11 | vi N{1, 10, 100, 1000, 10000, ten(5)}; 12 | foreach (n, N) { 13 | vc a(n); 14 | _for (i, n) 15 | a[i] = rnd(0, mint::mod()); 16 | auto f = convolution_square(a); 17 | auto g = convolution(a, a); 18 | assert(f == g); 19 | } 20 | } 21 | void test1() { 22 | vi N{1, 10, 100, 1000, 10000, ten(5)}; 23 | foreach (n, N) { 24 | vi a(n); 25 | _for (i, n) 26 | a[i] = rnd(0, ten(9)); 27 | auto f = convolution_square(a); 28 | auto g = convolution(a, a); 29 | assert(f == g); 30 | } 31 | } 32 | void test() { 33 | test0(); 34 | test0(); 35 | test1(); 36 | } 37 | int main() { 38 | test(); 39 | 40 | dR(int, a, b); 41 | print(a + b); 42 | return 0; 43 | } -------------------------------------------------------------------------------- /test/custom/fft.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/aplusb" 2 | 3 | #include "all.hpp" 4 | #include "poly/ntt_avx2.hpp" 5 | #include "poly/convolution_fft.hpp" 6 | #include "poly/convolution.hpp" 7 | #include "random/base.hpp" 8 | 9 | void test() { 10 | vi N{1, 10, 100, 1000, 10000}; 11 | foreach (n, N) { 12 | vi a(n), b(n); 13 | _for (i, n) 14 | a[i] = rnd(0, 10); 15 | _for (i, n) 16 | b[i] = rnd(0, 10); 17 | auto c = convolution_fft(a, b); 18 | auto d = convolution(a, b); 19 | assert(c == d); 20 | } 21 | N = {5 * ten(5), ten(6)}; 22 | foreach (n, N) { 23 | vi a(n), b(n); 24 | _for (i, n) 25 | a[i] = rnd(0, 10); 26 | _for (i, n) 27 | b[i] = rnd(0, 10); 28 | auto c = convolution_fft(a, b); 29 | auto d = convolution(a, b); 30 | assert(c == d); 31 | } 32 | } 33 | int main() { 34 | test(); 35 | 36 | dR(int, a, b); 37 | print(a + b); 38 | return 0; 39 | } -------------------------------------------------------------------------------- /test/custom/interval_union.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/aplusb" 2 | 3 | #include "all.hpp" 4 | #include "random/base.hpp" 5 | #include "utility/interval_union.hpp" 6 | 7 | void test(int n) { 8 | vi v(n + 1); 9 | vc a; 10 | _for (Min(rnd(0, n / 2), rnd(0, n / 2))) { 11 | int l, r; 12 | do { 13 | l = rnd(0, n); 14 | r = rnd(0, n + 1); 15 | } while (l > r || std::abs(l - r) > 10); 16 | a.eb(l, r); 17 | _for (i, l, r) 18 | v[i] = 1; 19 | } 20 | auto ret = interval_union(a); 21 | _for (i, len(ret) - 1) 22 | assert(ret[i].second < ret[i + 1].first); 23 | foreach (l, r, ret) 24 | _for (i, l, r) { 25 | assert(v[i]); 26 | v[i] = 0; 27 | } 28 | assert(!sum(v)); 29 | } 30 | void test() { 31 | _for (i, 100000) 32 | test(10); 33 | _for (i, 10000) 34 | test(100); 35 | _for (i, 1000) 36 | test(1000); 37 | } 38 | int main() { 39 | test(); 40 | 41 | dR(int, v, b); 42 | print(v + b); 43 | return 0; 44 | } -------------------------------------------------------------------------------- /test/custom/is_substring.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/aplusb" 2 | 3 | #include "all.hpp" 4 | #include "string/is_substring.hpp" 5 | #include "random/base.hpp" 6 | 7 | str gen(int n) { 8 | str s; 9 | _for (n) 10 | s += char('a' + rnd(0, 3)); 11 | return s; 12 | } 13 | void test() { 14 | _for (1000) 15 | _for (n, 1, 10) 16 | _for (m, 1, 10) { 17 | str s = gen(n), t = gen(m); 18 | assert(is_substring(s, t) == (t.find(s) != t.npos)); 19 | } 20 | } 21 | int main() { 22 | test(); 23 | 24 | dR(int, a, b); 25 | print(a + b); 26 | return 0; 27 | } -------------------------------------------------------------------------------- /test/library_checker/addition_of_big_integers.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/addition_of_big_integers" 2 | 3 | #include "all.hpp" 4 | #include "math/bigint.hpp" 5 | 6 | int main() { 7 | multipleTests([&] { 8 | dR(bigint, a, b); 9 | print(a + b); 10 | }); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /test/library_checker/aplusb.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/aplusb" 2 | 3 | #include "all.hpp" 4 | 5 | int main() { 6 | dR(int, a, b); 7 | print(a + b); 8 | return 0; 9 | } -------------------------------------------------------------------------------- /test/library_checker/area_of_union_of_rectangles.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/area_of_union_of_rectangles" 2 | 3 | #include "all.hpp" 4 | #include "ds/rectangle_union.hpp" 5 | 6 | int main() { 7 | dR(int, n); 8 | Rectangle_Union ru; 9 | _for (n) { 10 | dR(int, xl, yl, xr, yr); 11 | ru.add(xl, xr, yl, yr); 12 | } 13 | print(ru.calc()); 14 | return 0; 15 | } -------------------------------------------------------------------------------- /test/library_checker/associative_array.reserve.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/associative_array" 2 | 3 | #include "all.hpp" 4 | #include "ds/hashmap.hpp" 5 | 6 | int main() { 7 | dR(u32, q); 8 | HashMap mp(q); 9 | _for (q) { 10 | dR(u32, t); 11 | if (t == 0) { 12 | dR(u64, k, v); 13 | mp[k] = v; 14 | } 15 | else { 16 | dR(u64, k); 17 | print(mp.get(k, 0)); 18 | } 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /test/library_checker/associative_array.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/associative_array" 2 | 3 | #include "all.hpp" 4 | #include "ds/hashmap.hpp" 5 | 6 | int main() { 7 | dR(u32, q); 8 | HashMap mp; 9 | _for (q) { 10 | dR(u32, t); 11 | if (t == 0) { 12 | dR(u64, k, v); 13 | mp[k] = v; 14 | } 15 | else { 16 | dR(u64, k); 17 | print(mp.get(k, 0)); 18 | } 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /test/library_checker/biconnected_components.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/biconnected_components" 2 | 3 | #include "all.hpp" 4 | #include "graph/block_cut_tree.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | auto g = read_graph(n, m, 0); 9 | auto bct = block_cut_tree(g); 10 | print(bct.n - n); 11 | _for (i, n, bct.n) { 12 | vi ans; 13 | foreach (j, bct[i]) 14 | if (j < n) 15 | ans.eb(j); 16 | print(len(ans), ans); 17 | } 18 | return 0; 19 | } -------------------------------------------------------------------------------- /test/library_checker/binomial_coefficient_prime_mod.no_extend.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/binomial_coefficient_prime_mod" 2 | 3 | #define COMB_EXTEND false 4 | #include "all.hpp" 5 | #include "modint/binomial.hpp" 6 | #include "modint/montgomery.hpp" 7 | 8 | int main() { 9 | dR(u32, T, mod); 10 | if (mod == 2) { 11 | _for (T) { 12 | dR(u32, n, k); 13 | print(n != 0 || k != 1); 14 | } 15 | return 0; 16 | } 17 | SetMMod(u32, mod); 18 | comb.extend(ten(7)); 19 | _for (T) { 20 | dR(u32, n, k); 21 | print(C(n, k)); 22 | } 23 | return 0; 24 | } -------------------------------------------------------------------------------- /test/library_checker/binomial_coefficient_prime_mod.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/binomial_coefficient_prime_mod" 2 | 3 | #include "all.hpp" 4 | #include "modint/binomial.hpp" 5 | #include "modint/montgomery.hpp" 6 | 7 | int main() { 8 | dR(u32, T, mod); 9 | if (mod == 2) { 10 | _for (T) { 11 | dR(u32, n, k); 12 | print(n != 0 || k != 1); 13 | } 14 | return 0; 15 | } 16 | SetMMod(u32, mod); 17 | _for (T) { 18 | dR(u32, n, k); 19 | print(C(n, k)); 20 | } 21 | return 0; 22 | } -------------------------------------------------------------------------------- /test/library_checker/characteristic_polynomial.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/characteristic_polynomial" 2 | 3 | #include "all.hpp" 4 | #include "modint/montgomery.hpp" 5 | #include "linalg/characteristic_poly.hpp" 6 | 7 | int main() { 8 | dR(int, n); 9 | using mint = MMInt998244353; 10 | dRV(mint, a, n, n); 11 | print(characteristic_poly(std::move(a))); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /test/library_checker/convolution_mod.avx2.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod" 2 | 3 | #include "all.hpp" 4 | #include "poly/ntt_avx2.hpp" 5 | #include "poly/convolution.hpp" 6 | 7 | using mint = MMInt998244353; 8 | int main() { 9 | dR(int, n, m); 10 | dRV(mint, a, n); 11 | dRV(mint, b, m); 12 | print(convolution(a, b)); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /test/library_checker/convolution_mod.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod" 2 | 3 | #include "all.hpp" 4 | #include "poly/convolution.hpp" 5 | 6 | using mint = MMInt998244353; 7 | int main() { 8 | dR(int, n, m); 9 | dRV(mint, a, n); 10 | dRV(mint, b, m); 11 | print(convolution(a, b)); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /test/library_checker/convolution_mod_1000000007.avx2.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod_1000000007" 2 | 3 | #include "all.hpp" 4 | #include "poly/ntt_avx2.hpp" 5 | #include "poly/convolution.hpp" 6 | 7 | using mint = MMInt1000000007; 8 | int main() { 9 | dR(int, n, m); 10 | dRV(mint, a, n); 11 | dRV(mint, b, m); 12 | print(convolution(a, b)); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /test/library_checker/convolution_mod_1000000007.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod_1000000007" 2 | 3 | #include "all.hpp" 4 | #include "poly/convolution.hpp" 5 | 6 | using mint = MMInt1000000007; 7 | int main() { 8 | dR(int, n, m); 9 | dRV(mint, a, n); 10 | dRV(mint, b, m); 11 | print(convolution(a, b)); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /test/library_checker/convolution_mod_large.avx2.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod_large" 2 | 3 | #include "all.hpp" 4 | #include "poly/ntt_avx2.hpp" 5 | #include "poly/convolution.hpp" 6 | 7 | using mint = MMInt998244353; 8 | int main() { 9 | dR(int, n, m); 10 | dRV(mint, a, n); 11 | dRV(mint, b, m); 12 | print(convolution(a, b)); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /test/library_checker/convolution_mod_large.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod_large" 2 | 3 | #include "all.hpp" 4 | #include "poly/convolution_huge.hpp" 5 | 6 | using mint = MMInt998244353; 7 | int main() { 8 | dR(int, n, m); 9 | dRV(mint, a, n); 10 | dRV(mint, b, m); 11 | print(convolution_huge(a, b)); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /test/library_checker/counting_primes.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/counting_primes" 2 | 3 | #include "all.hpp" 4 | #include "math/prime/counting.hpp" 5 | 6 | int main() { 7 | dR(i64, n); 8 | print(prime_counting(n)); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /test/library_checker/cycle_detection.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/cycle_detection" 2 | 3 | #include "all.hpp" 4 | #include "graph/find_cycle.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | auto g = read_graph(n, m, 0); 9 | auto [vs, es] = find_cycle(g); 10 | if (vs.empty()) { 11 | print(-1); 12 | } 13 | else { 14 | print(len(es)); 15 | io.displayArray(es, '\n'); 16 | } 17 | return 0; 18 | } -------------------------------------------------------------------------------- /test/library_checker/cycle_detection_undirected.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/cycle_detection_undirected" 2 | 3 | #include "all.hpp" 4 | #include "graph/find_cycle.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | auto g = read_graph(n, m, 0); 9 | auto [vs, es] = find_cycle(g); 10 | if (vs.empty()) { 11 | print(-1); 12 | } 13 | else { 14 | print(len(vs)); 15 | print(vs); 16 | print(es); 17 | } 18 | return 0; 19 | } -------------------------------------------------------------------------------- /test/library_checker/cycle_detection_undirected_minimal.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/cycle_detection_undirected" 2 | 3 | #include "all.hpp" 4 | #include "graph/find_cycle.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | auto g = read_graph(n, m, 0); 9 | auto [vs, es] = find_cycle(g, true); 10 | if (vs.empty()) { 11 | print(-1); 12 | } 13 | else { 14 | print(len(vs)); 15 | print(vs); 16 | print(es); 17 | } 18 | return 0; 19 | } -------------------------------------------------------------------------------- /test/library_checker/deque_operate_all_composite.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/deque_operate_all_composite" 2 | 3 | #include "all.hpp" 4 | #include "ds/swag.hpp" 5 | #include "modint/montgomery.hpp" 6 | #include "monoid/affine.hpp" 7 | 8 | using mint = MMInt998244353; 9 | int main() { 10 | dR(int, q); 11 | using Mono = Monoid_Affine; 12 | SWAG_deque swag; 13 | _for (q) { 14 | dR(int, t); 15 | if (t == 0) { 16 | dR(int, a, b); 17 | swag.emplace_front(a, b); 18 | } 19 | if (t == 1) { 20 | dR(int, a, b); 21 | swag.emplace_back(a, b); 22 | } 23 | if (t == 2) { 24 | swag.pop_front(); 25 | } 26 | if (t == 3) { 27 | swag.pop_back(); 28 | } 29 | if (t == 4) { 30 | dR(int, x); 31 | print(Mono::eval(swag.prod(), x)); 32 | } 33 | } 34 | return 0; 35 | } -------------------------------------------------------------------------------- /test/library_checker/directedmst.pool.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/directedmst" 2 | 3 | #include "all.hpp" 4 | #include "graph/minimum_cost_arborescence.hpp" 5 | 6 | int main() { 7 | dR(int, n, m, s); 8 | auto g = read_graph(n, m, 0); 9 | auto [cost, I] = MinimumCostArborescence(g, s); 10 | vi par(n); 11 | par[s] = s; 12 | foreach (i, I) { 13 | auto&& e = g.edges[i]; 14 | par[e.to] = e.from; 15 | } 16 | print(cost); 17 | print(par); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /test/library_checker/directedmst.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/directedmst" 2 | 3 | #include "all.hpp" 4 | #include "graph/minimum_cost_arborescence.hpp" 5 | 6 | int main() { 7 | dR(int, n, m, s); 8 | auto g = read_graph(n, m, 0); 9 | auto [cost, I] = MinimumCostArborescence<4 * ten(5)>(g, s); 10 | vi par(n); 11 | par[s] = s; 12 | foreach (i, I) { 13 | auto&& e = g.edges[i]; 14 | par[e.to] = e.from; 15 | } 16 | print(cost); 17 | print(par); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /test/library_checker/discrete_logarithm_mod.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/discrete_logarithm_mod" 2 | 3 | #include "all.hpp" 4 | #include "modint/mod_log.hpp" 5 | 6 | int main() { 7 | multipleTests([&] { 8 | dR(u32, x, y, p); 9 | print(int(mod_log(x, y, p).value_or(-1))); 10 | }); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /test/library_checker/division_of_big_integers.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/division_of_big_integers" 2 | 3 | #include "all.hpp" 4 | #include "math/bigint.hpp" 5 | 6 | int main() { 7 | multipleTests([&] { 8 | dR(bigint, a, b); 9 | print(divmod(a, b)); 10 | }); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /test/library_checker/double_ended_priority_queue.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/double_ended_priority_queue" 2 | 3 | #include "all.hpp" 4 | #include "ds/removable_queue.hpp" 5 | 6 | int main() { 7 | dR(int, n, q); 8 | dRV(int, a, n); 9 | RemovableQueue> q1(a); 10 | RemovableQueue> q2(a); 11 | _for (q) { 12 | dR(char, t); 13 | if (t == '0') { 14 | dR(int, x); 15 | q1.push(x), q2.push(x); 16 | } 17 | else if (t == '1') { 18 | int x = q1.pop(); 19 | q2.remove(x); 20 | print(x); 21 | } 22 | else { 23 | int x = q2.pop(); 24 | q1.remove(x); 25 | print(x); 26 | } 27 | } 28 | return 0; 29 | } -------------------------------------------------------------------------------- /test/library_checker/enumerate_primes.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/enumerate_primes" 2 | 3 | #include "all.hpp" 4 | #include "math/prime/sieve.hpp" 5 | 6 | int main() { 7 | dR(int, n, a, b); 8 | auto primes = prime_sieve(n); 9 | vi ans; 10 | while (b < len(primes)) 11 | ans.eb(primes[b]), b += a; 12 | print(len(primes), len(ans)); 13 | print(ans); 14 | return 0; 15 | } -------------------------------------------------------------------------------- /test/library_checker/factorize.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/factorize" 2 | 3 | #include "all.hpp" 4 | #include "math/factorize.hpp" 5 | 6 | int main() { 7 | multipleTests([&]() { 8 | dR(u64, n); 9 | auto ans = factorize(n); 10 | print(len(ans), ans); 11 | }); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /test/library_checker/frequency_table_of_tree_distance.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/frequency_table_of_tree_distance" 2 | 3 | #include "all.hpp" 4 | #include "poly/ntt_avx2.hpp" 5 | #include "graph/tree_all_distances.hpp" 6 | 7 | int main() { 8 | dR(int, n); 9 | auto g = read_tree(n, 0); 10 | auto ans = tree_all_distances(g); 11 | ans.erase(ans.begin()); 12 | foreach (x, ans) 13 | x >>= 1; 14 | print(ans); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /test/library_checker/inverse_matrix.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/inverse_matrix" 2 | 3 | #include "all.hpp" 4 | #include "modint/montgomery.hpp" 5 | #include "linalg/matrix_inv.hpp" 6 | 7 | using mint = MMInt998244353; 8 | int main() { 9 | dR(int, n); 10 | dRV(mint, a, n, n); 11 | auto [b, det] = matrix_inv(a); 12 | if (det != 0) 13 | print(b); 14 | else 15 | print(-1); 16 | return 0; 17 | } -------------------------------------------------------------------------------- /test/library_checker/jump_on_tree.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/jump_on_tree" 2 | 3 | #include "all.hpp" 4 | #include "graph/tree.hpp" 5 | 6 | int main() { 7 | dR(int, n, q); 8 | auto g = read_tree(n, 0); 9 | Tree tree(g); 10 | _for (q) { 11 | dR(int, u, v, x); 12 | print(tree.jump(u, v, x)); 13 | } 14 | return 0; 15 | } -------------------------------------------------------------------------------- /test/library_checker/k_shortest_walk.pool.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/k_shortest_walk" 2 | 3 | #include "all.hpp" 4 | #include "graph/K_shortest_walk.hpp" 5 | 6 | int main() { 7 | dR(int, n, m, s, t, k); 8 | auto g = read_graph(n, m, 0); 9 | auto ret = K_shortest_walk(g, s, t, k); 10 | foreach (r, ret) 11 | if (r == inf) 12 | r = -1; 13 | io.displayArray(ret, '\n'); 14 | return 0; 15 | } -------------------------------------------------------------------------------- /test/library_checker/k_shortest_walk.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/k_shortest_walk" 2 | 3 | #include "all.hpp" 4 | #include "graph/K_shortest_walk.hpp" 5 | 6 | int main() { 7 | dR(int, n, m, s, t, k); 8 | auto g = read_graph(n, m, 0); 9 | auto ret = K_shortest_walk(g, s, t, k); 10 | foreach (r, ret) 11 | if (r == inf) 12 | r = -1; 13 | io.displayArray(ret, '\n'); 14 | return 0; 15 | } -------------------------------------------------------------------------------- /test/library_checker/kth_root_integer.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/kth_root_integer" 2 | 3 | #include "all.hpp" 4 | #include "math/inth_root.hpp" 5 | 6 | int main() { 7 | multipleTests([&] { 8 | dR(u64, n, k); 9 | print(inth_root(n, k)); 10 | }); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /test/library_checker/lca.fast.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/lca" 2 | 3 | #include "all.hpp" 4 | #include "graph/fast_lca.hpp" 5 | 6 | int main() { 7 | dR(int, n, q); 8 | Graph g(n); 9 | _for (i, 1, n) { 10 | dR(int, p); 11 | g.add(p, i); 12 | } 13 | g.build(); 14 | Fast_Lca_Tree tree(g); 15 | _for (q) { 16 | dR(int, u, v); 17 | print(tree.lca(u, v)); 18 | } 19 | return 0; 20 | } -------------------------------------------------------------------------------- /test/library_checker/lca.lid.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/lca" 2 | 3 | #include "all.hpp" 4 | #include "ds/static_range_product.hpp" 5 | #include "ds/sparse_table.hpp" 6 | #include "monoid/min.hpp" 7 | 8 | int main() { 9 | dR(int, n, q); 10 | vi fa(n); 11 | io.readArray(1 + all(fa)); 12 | vi lid(n); 13 | _for_r (i, 1, n) 14 | lid[fa[i]] += lid[i] + 1; 15 | _for (i, 1, n) 16 | lid[i] = std::exchange(lid[fa[i]], lid[fa[i]] - lid[i] - 1); 17 | vi a(n); 18 | _for (i, 1, n) { 19 | a[lid[i] - 1] = fa[i]; 20 | } 21 | Static_Range_Product> st(a); 22 | _for (q) { 23 | dR(int, u, v); 24 | u = lid[u], v = lid[v]; 25 | if (u > v) 26 | swap(u, v); 27 | print(st.prod(u, v)); 28 | } 29 | return 0; 30 | } -------------------------------------------------------------------------------- /test/library_checker/lca.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/lca" 2 | 3 | #include "all.hpp" 4 | #include "graph/tree.hpp" 5 | 6 | int main() { 7 | dR(int, n, q); 8 | Graph g(n); 9 | _for (i, 1, n) { 10 | dR(int, p); 11 | g.add(p, i); 12 | } 13 | g.build(); 14 | Tree tree(g); 15 | _for (q) { 16 | dR(int, u, v); 17 | print(tree.lca(u, v)); 18 | } 19 | return 0; 20 | } -------------------------------------------------------------------------------- /test/library_checker/longest_increasing_subsequence.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/longest_increasing_subsequence" 2 | 3 | #include "all.hpp" 4 | #include "seq/longest_increasing_subsequence.hpp" 5 | 6 | int main() { 7 | dR(int, n); 8 | dRV(int, a, n); 9 | auto I = longest_increasing_sequence_id(a); 10 | print(len(I)); 11 | print(I); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /test/library_checker/manhattanmst.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/manhattanmst" 2 | 3 | #include "all.hpp" 4 | #include "graph/manhattan_mst.hpp" 5 | 6 | int main() { 7 | dR(int, n); 8 | dRV(pi, a, n); 9 | auto mst = manhattan_mst(a); 10 | i64 ans = 0; 11 | foreach (e, mst.edges) 12 | ans += e.cost; 13 | print(ans); 14 | foreach (e, mst.edges) 15 | print(e.from, e.to); 16 | return 0; 17 | } -------------------------------------------------------------------------------- /test/library_checker/many_aplusb.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/many_aplusb" 2 | 3 | #include "all.hpp" 4 | 5 | int main() { 6 | multipleTests([&] { 7 | dR(i64, a, b); 8 | print(a + b); 9 | }); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /test/library_checker/many_aplusb_128bit.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/many_aplusb_128bit" 2 | 3 | #include "all.hpp" 4 | 5 | int main() { 6 | multipleTests([&] { 7 | dR(i128, a, b); 8 | print(a + b); 9 | }); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /test/library_checker/matrix_det.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/matrix_det" 2 | 3 | #include "all.hpp" 4 | #include "modint/montgomery.hpp" 5 | #include "linalg/matrix_det.hpp" 6 | 7 | using mint = MMInt998244353; 8 | int main() { 9 | dR(int, n); 10 | dRV(mint, a, n, n); 11 | print(matrix_det(a)); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /test/library_checker/matrix_det_arbitrary_mod.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/matrix_det_arbitrary_mod" 2 | 3 | #include "all.hpp" 4 | #include "linalg/matrix_det.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | dRV(u32, a, n, n); 9 | print(matrix_det_mod(a, m)); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /test/library_checker/matrix_product.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/matrix_product" 2 | 3 | #include "all.hpp" 4 | #include "modint/montgomery.hpp" 5 | #include "linalg/matrix_mul.hpp" 6 | 7 | using mint = MMInt998244353; 8 | int main() { 9 | dR(int, n, m, k); 10 | dRV(mint, a, n, m); 11 | dRV(mint, b, m, k); 12 | print(matrix_mul(a, b)); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /test/library_checker/matrix_product_mod_2.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/matrix_product_mod_2" 2 | 3 | #include "all.hpp" 4 | #include "ds/bitset.hpp" 5 | 6 | int main() { 7 | dR(int, n, m, k); 8 | dRV(bitset, a, n); 9 | dRV(bitset, b, m); 10 | vc c(n, bitset(k)); 11 | _for (i, n) 12 | _for (j, m) 13 | if (a[i][j]) 14 | c[i] ^= b[j]; 15 | io.displayArray(c, '\n'); 16 | return 0; 17 | } -------------------------------------------------------------------------------- /test/library_checker/minimum_spanning_tree.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/minimum_spanning_tree" 2 | 3 | #include "all.hpp" 4 | #include "graph/kruskal.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | auto g = read_graph(n, m, 0); 9 | auto [cost, in, _] = kruskal(g); 10 | print(cost); 11 | vi ans; 12 | _for (i, m) 13 | if (in[i]) 14 | ans.eb(i); 15 | print(ans); 16 | return 0; 17 | } -------------------------------------------------------------------------------- /test/library_checker/multiplication_of_big_integers.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/multiplication_of_big_integers" 2 | 3 | #include "all.hpp" 4 | #include "math/bigint.hpp" 5 | 6 | int main() { 7 | multipleTests([&] { 8 | dR(bigint, a, b); 9 | print(a * b); 10 | }); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /test/library_checker/number_of_subsequences.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/number_of_subsequences" 2 | 3 | #include "all.hpp" 4 | #include "modint/montgomery.hpp" 5 | #include "string/count_subsequence.hpp" 6 | 7 | using mint = MMInt998244353; 8 | int main() { 9 | dR(int, n); 10 | dRV(int, a, n); 11 | print(count_subsequence(a)); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /test/library_checker/persistent_queue.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/persistent_queue" 2 | 3 | #include "all.hpp" 4 | #include "ds/dynamic_array.hpp" 5 | 6 | int main() { 7 | dR(int, q); 8 | Dynamic_Array a(q); 9 | using np = decltype(a)::np; 10 | vc roots{a.new_node()}; 11 | vi L{0}, R{0}; 12 | _for (q) { 13 | dR(int, op, t), t++; 14 | np u = roots[t]; 15 | int l = L[t], r = R[t]; 16 | if (op == 0) { 17 | dR(int, x); 18 | u = a.set(u, r++, x); 19 | } 20 | else { 21 | print(a.get(u, l++)); 22 | } 23 | roots.eb(u); 24 | L.eb(l); 25 | R.eb(r); 26 | } 27 | return 0; 28 | } -------------------------------------------------------------------------------- /test/library_checker/persistent_unionfind.pool.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/persistent_unionfind" 2 | 3 | #include "all.hpp" 4 | #include "ds/dynamic_unionfind.hpp" 5 | 6 | int main() { 7 | dR(int, n, q); 8 | Dynamic_UnionFind uf; 9 | using np = decltype(uf)::np; 10 | vc roots{uf.new_node()}; 11 | _for (q) { 12 | dR(int, t, k, u, v), k++; 13 | np r = roots[k]; 14 | if (t == 0) { 15 | auto [nr, b] = uf.merge(r, u, v); 16 | r = nr; 17 | } 18 | else 19 | print(uf.same(r, u, v)); 20 | roots.eb(r); 21 | } 22 | return 0; 23 | } -------------------------------------------------------------------------------- /test/library_checker/persistent_unionfind.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/persistent_unionfind" 2 | 3 | #include "all.hpp" 4 | #include "ds/dynamic_unionfind.hpp" 5 | 6 | int main() { 7 | dR(int, n, q); 8 | Dynamic_UnionFind uf; 9 | using np = decltype(uf)::np; 10 | vc roots{uf.new_node()}; 11 | _for (q) { 12 | dR(int, t, k, u, v), k++; 13 | np r = roots[k]; 14 | if (t == 0) { 15 | auto [nr, b] = uf.merge(r, u, v); 16 | r = nr; 17 | } 18 | else 19 | print(uf.same(r, u, v)); 20 | roots.eb(r); 21 | } 22 | return 0; 23 | } -------------------------------------------------------------------------------- /test/library_checker/point_add_range_sum.seg.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/point_add_range_sum" 2 | 3 | #include "all.hpp" 4 | #include "ds/segtree.hpp" 5 | #include "monoid/add.hpp" 6 | 7 | int main() { 8 | dR(int, n, q); 9 | SegTree> st(n, [&](int) { return io.read(); }); 10 | _for (q) { 11 | dR(int, t, x, y); 12 | if (t == 0) { 13 | st.multiply(x, y); 14 | } 15 | else { 16 | print(st.prod(x, y)); 17 | } 18 | } 19 | return 0; 20 | } -------------------------------------------------------------------------------- /test/library_checker/point_add_range_sum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/point_add_range_sum" 2 | 3 | #include "all.hpp" 4 | #include "ds/fenwicktree.hpp" 5 | #include "monoid/add.hpp" 6 | 7 | int main() { 8 | dR(int, n, q); 9 | FenwickTree> bit(n, [&](int) { return io.read(); }); 10 | _for (q) { 11 | dR(int, t, x, y); 12 | if (t == 0) { 13 | bit.multiply(x, y); 14 | } 15 | else { 16 | print(bit.prod(x, y)); 17 | } 18 | } 19 | return 0; 20 | } -------------------------------------------------------------------------------- /test/library_checker/point_add_range_sum.wseg.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/point_add_range_sum" 2 | 3 | #include "all.hpp" 4 | #include "ds/wide_segtree.hpp" 5 | #include "monoid/add.hpp" 6 | 7 | int main() { 8 | dR(int, n, q); 9 | Wide_SegTree> seg(n, [&](int) { return io.read(); }); 10 | _for (q) { 11 | dR(int, t, x, y); 12 | if (t == 0) { 13 | seg.multiply(x, y); 14 | } 15 | else { 16 | print(seg.prod(x, y)); 17 | } 18 | } 19 | return 0; 20 | } -------------------------------------------------------------------------------- /test/library_checker/point_set_range_composite.dynamic.pool.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/point_set_range_composite" 2 | 3 | #include "all.hpp" 4 | #include "modint/montgomery.hpp" 5 | #include "ds/dynamic_segtree.hpp" 6 | #include "monoid/affine.hpp" 7 | 8 | int main() { 9 | dR(int, n, q); 10 | using mint = MMInt998244353; 11 | using Mono = Monoid_Affine; 12 | using X = Mono::value_type; 13 | dRV(X, a, n); 14 | Dynamic_SegTree st(0, n); 15 | using np = decltype(st)::np; 16 | np root = st.new_node(a); 17 | _for (q) { 18 | dR(int, t, x, y, z); 19 | if (t == 0) { 20 | st.set(root, x, {y, z}); 21 | } 22 | else { 23 | print(Mono::eval(st.prod(root, x, y), z)); 24 | } 25 | } 26 | return 0; 27 | } -------------------------------------------------------------------------------- /test/library_checker/point_set_range_composite.dynamic.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/point_set_range_composite" 2 | 3 | #include "all.hpp" 4 | #include "modint/montgomery.hpp" 5 | #include "ds/dynamic_segtree.hpp" 6 | #include "monoid/affine.hpp" 7 | 8 | int main() { 9 | dR(int, n, q); 10 | using mint = MMInt998244353; 11 | using Mono = Monoid_Affine; 12 | using X = Mono::value_type; 13 | dRV(X, a, n); 14 | Dynamic_SegTree st(0, n); 15 | using np = decltype(st)::np; 16 | np root = st.new_node(a); 17 | _for (q) { 18 | dR(int, t, x, y, z); 19 | if (t == 0) { 20 | st.set(root, x, {y, z}); 21 | } 22 | else { 23 | print(Mono::eval(st.prod(root, x, y), z)); 24 | } 25 | } 26 | return 0; 27 | } -------------------------------------------------------------------------------- /test/library_checker/point_set_range_composite.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/point_set_range_composite" 2 | 3 | #include "all.hpp" 4 | #include "modint/montgomery.hpp" 5 | #include "ds/segtree.hpp" 6 | #include "monoid/affine.hpp" 7 | 8 | int main() { 9 | dR(int, n, q); 10 | using mint = MMInt998244353; 11 | using Mono = Monoid_Affine; 12 | SegTree st(n, [&](int) -> Mono::X { 13 | dR(int, x, y); 14 | return {x, y}; 15 | }); 16 | _for (q) { 17 | dR(int, t, x, y, z); 18 | if (t == 0) { 19 | st.set(x, {y, z}); 20 | } 21 | else { 22 | print(Mono::eval(st.prod(x, y), z)); 23 | } 24 | } 25 | return 0; 26 | } -------------------------------------------------------------------------------- /test/library_checker/pow_of_matrix.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/pow_of_matrix" 2 | 3 | #include "all.hpp" 4 | #include "modint/montgomery.hpp" 5 | #include "linalg/matrix_pow.hpp" 6 | 7 | using mint = MMInt998244353; 8 | int main() { 9 | dR(int, n); 10 | dR(i64, k); 11 | dRV(mint, a, n, n); 12 | print(matrix_pow(a, k)); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /test/library_checker/predecessor_problem.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/predecessor_problem" 2 | 3 | #include "all.hpp" 4 | #include "ds/fastset.hpp" 5 | 6 | int main() { 7 | dR(u32, n, q); 8 | STR(s, n); 9 | FastSet st(n); 10 | _for (i, n) 11 | if (s[i] == '1') 12 | st.insert(i); 13 | _for (q) { 14 | dR(u32, t, x); 15 | if (t == 0) 16 | st.insert(x); 17 | else if (t == 1) 18 | st.erase(x); 19 | else if (t == 2) 20 | print(st.contains(x)); 21 | else if (t == 4) 22 | print(st.prev(x)); 23 | else { 24 | u32 r = st.next(x); 25 | if (r == n) 26 | print(-1); 27 | else 28 | print(r); 29 | } 30 | } 31 | return 0; 32 | } -------------------------------------------------------------------------------- /test/library_checker/primality_test.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/primality_test" 2 | 3 | #include "all.hpp" 4 | #include "math/prime/test.hpp" 5 | 6 | int main() { 7 | multipleTests([&] { 8 | dR(u64, x); 9 | Yes(is_prime(x)); 10 | }); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /test/library_checker/primitive_root.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/primitive_root" 2 | 3 | #include "all.hpp" 4 | #include "math/primitive_root.hpp" 5 | 6 | int main() { 7 | multipleTests([&] { 8 | dR(u64, x); 9 | print(primitive_root(x)); 10 | }); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /test/library_checker/queue_operate_all_composite.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/queue_operate_all_composite" 2 | 3 | #include "all.hpp" 4 | #include "ds/swag.hpp" 5 | #include "modint/montgomery.hpp" 6 | #include "monoid/affine.hpp" 7 | 8 | using mint = MMInt998244353; 9 | int main() { 10 | dR(int, q); 11 | using Mono = Monoid_Affine; 12 | SWAG swag; 13 | _for (q) { 14 | dR(int, t); 15 | if (t == 0) { 16 | dR(int, a, b); 17 | swag.emplace(a, b); 18 | } 19 | if (t == 1) { 20 | swag.pop(); 21 | } 22 | if (t == 2) { 23 | dR(int, x); 24 | print(Mono::eval(swag.prod(), x)); 25 | } 26 | } 27 | return 0; 28 | } -------------------------------------------------------------------------------- /test/library_checker/range_affine_point_get.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/range_affine_point_get" 2 | 3 | #include "all.hpp" 4 | #include "modint/montgomery.hpp" 5 | #include "ds/dual_segtree.hpp" 6 | #include "monoid/affine.hpp" 7 | 8 | int main() { 9 | dR(u32, n, q); 10 | using mint = MMInt998244353; 11 | dRV(mint, a, n); 12 | using Mono = Monoid_Affine; 13 | Dual_SegTree st(n); 14 | _for (q) { 15 | dR(u32, t); 16 | if (t == 0) { 17 | dR(u32, l, r, x, y); 18 | st.apply(l, r, {x, y}); 19 | } 20 | else { 21 | dR(u32, p); 22 | auto [x, y] = st.get(p); 23 | print(x * a[p] + y); 24 | } 25 | } 26 | return 0; 27 | } -------------------------------------------------------------------------------- /test/library_checker/range_affine_range_sum.dynamic.pool.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/range_affine_range_sum" 2 | 3 | #include "all.hpp" 4 | #include "modint/montgomery.hpp" 5 | #include "ds/dynamic_lazy_segtree.hpp" 6 | #include "acted_monoid/sum_affine.hpp" 7 | 8 | int main() { 9 | dR(u32, n, q); 10 | using mint = MMInt998244353; 11 | dRV(mint, a, n); 12 | Dynamic_Lazy_SegTree, false> st(0, n); 13 | using np = decltype(st)::np; 14 | np root = st.new_node(a); 15 | _for (q) { 16 | dR(u32, t, l, r); 17 | if (t == 0) { 18 | dR(u32, x, y); 19 | root = st.apply(root, l, r, {x, y}); 20 | } 21 | else { 22 | print(st.prod(root, l, r)); 23 | } 24 | } 25 | return 0; 26 | } -------------------------------------------------------------------------------- /test/library_checker/range_affine_range_sum.dynamic.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/range_affine_range_sum" 2 | 3 | #include "all.hpp" 4 | #include "modint/montgomery.hpp" 5 | #include "ds/dynamic_lazy_segtree.hpp" 6 | #include "acted_monoid/sum_affine.hpp" 7 | 8 | int main() { 9 | dR(u32, n, q); 10 | using mint = MMInt998244353; 11 | dRV(mint, a, n); 12 | Dynamic_Lazy_SegTree, false, int, 2 * ten(6)> st(0, n); 13 | using np = decltype(st)::np; 14 | np root = st.new_node(a); 15 | _for (q) { 16 | dR(u32, t, l, r); 17 | if (t == 0) { 18 | dR(u32, x, y); 19 | root = st.apply(root, l, r, {x, y}); 20 | } 21 | else { 22 | print(st.prod(root, l, r)); 23 | } 24 | } 25 | return 0; 26 | } -------------------------------------------------------------------------------- /test/library_checker/range_affine_range_sum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/range_affine_range_sum" 2 | 3 | #include "all.hpp" 4 | #include "modint/montgomery.hpp" 5 | #include "ds/lazy_segtree.hpp" 6 | #include "acted_monoid/sum_affine.hpp" 7 | 8 | int main() { 9 | dR(u32, n, q); 10 | using mint = MMInt998244353; 11 | Lazy_SegTree> st(n, [&](int) { return io.read(); }); 12 | _for (q) { 13 | dR(u32, t, l, r); 14 | if (t == 0) { 15 | dR(u32, x, y); 16 | st.apply(l, r, {x, y}); 17 | } 18 | else { 19 | print(st.prod(l, r)); 20 | } 21 | } 22 | return 0; 23 | } -------------------------------------------------------------------------------- /test/library_checker/range_chmin_chmax_add_range_sum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/range_chmin_chmax_add_range_sum" 2 | 3 | #include "all.hpp" 4 | #include "ds/beats_summinmax_addchminchmax.hpp" 5 | 6 | int main() { 7 | dR(u32, n, q); 8 | Beats_SumMinMax_AddChminChmax seg(n, [&](int) { return io.read(); }); 9 | _for (q) { 10 | dR(u32, t, l, r); 11 | if (t == 0) { 12 | dR(i64, x); 13 | seg.chmin(l, r, x); 14 | } 15 | else if (t == 1) { 16 | dR(i64, x); 17 | seg.chmax(l, r, x); 18 | } 19 | else if (t == 2) { 20 | dR(i64, x); 21 | seg.add(l, r, x); 22 | } 23 | else 24 | print(seg.prod(l, r).sum); 25 | } 26 | return 0; 27 | } -------------------------------------------------------------------------------- /test/library_checker/range_kth_smallest.pseg.pool.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/range_kth_smallest" 2 | 3 | #include "all.hpp" 4 | #include "ds/dynamic_segtree.hpp" 5 | #include "monoid/add.hpp" 6 | #include "math/binary_search.hpp" 7 | 8 | int main() { 9 | dR(int, n, m); 10 | dRV(int, a, n); 11 | Dynamic_SegTree, true> seg(0, n); 12 | using np = decltype(seg)::np; 13 | auto I = argsort(a); 14 | vc roots{seg.new_node()}; 15 | _for (i, n) 16 | roots.eb(seg.set(roots.back(), I[i], 1)); 17 | _for (m) { 18 | dR(int, l, r, k); 19 | auto check = [&](auto mi) { return seg.prod(roots[mi], l, r) <= k; }; 20 | print(a[I[bsearch(check, 0, n)]]); 21 | } 22 | return 0; 23 | } -------------------------------------------------------------------------------- /test/library_checker/range_kth_smallest.pseg.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/range_kth_smallest" 2 | 3 | #include "all.hpp" 4 | #include "ds/dynamic_segtree.hpp" 5 | #include "monoid/add.hpp" 6 | #include "math/binary_search.hpp" 7 | 8 | int main() { 9 | dR(int, n, m); 10 | dRV(int, a, n); 11 | Dynamic_SegTree, true, int, 4 * ten(6)> seg(0, n); 12 | using np = decltype(seg)::np; 13 | auto I = argsort(a); 14 | vc roots{seg.new_node()}; 15 | _for (i, n) 16 | roots.eb(seg.set(roots.back(), I[i], 1)); 17 | _for (m) { 18 | dR(int, l, r, k); 19 | auto check = [&](auto mi) { return seg.prod(roots[mi], l, r) <= k; }; 20 | print(a[I[bsearch(check, 0, n)]]); 21 | } 22 | return 0; 23 | } -------------------------------------------------------------------------------- /test/library_checker/range_kth_smallest.pseg_sparse.pool.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/range_kth_smallest" 2 | 3 | #include "all.hpp" 4 | #include "ds/dynamic_segtree_sparse.hpp" 5 | #include "monoid/add.hpp" 6 | #include "math/binary_search.hpp" 7 | 8 | int main() { 9 | dR(int, n, m); 10 | dRV(int, a, n); 11 | Dynamic_SegTree_Sparse, true> seg(0, n); 12 | using np = decltype(seg)::np; 13 | auto I = argsort(a); 14 | vc roots{seg.new_node()}; 15 | _for (i, n) 16 | roots.eb(seg.set(roots.back(), I[i], 1)); 17 | _for (m) { 18 | dR(int, l, r, k); 19 | auto check = [&](auto mi) { return seg.prod(roots[mi], l, r) <= k; }; 20 | print(a[I[bsearch(check, 0, n)]]); 21 | } 22 | return 0; 23 | } -------------------------------------------------------------------------------- /test/library_checker/range_kth_smallest.pseg_sparse.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/range_kth_smallest" 2 | 3 | #include "all.hpp" 4 | #include "ds/dynamic_segtree_sparse.hpp" 5 | #include "monoid/add.hpp" 6 | #include "math/binary_search.hpp" 7 | 8 | int main() { 9 | dR(int, n, m); 10 | dRV(int, a, n); 11 | Dynamic_SegTree_Sparse, true, int, 4 * ten(6)> seg(0, n); 12 | using np = decltype(seg)::np; 13 | auto I = argsort(a); 14 | vc roots{seg.new_node()}; 15 | _for (i, n) 16 | roots.eb(seg.set(roots.back(), I[i], 1)); 17 | _for (m) { 18 | dR(int, l, r, k); 19 | auto check = [&](auto mi) { return seg.prod(roots[mi], l, r) <= k; }; 20 | print(a[I[bsearch(check, 0, n)]]); 21 | } 22 | return 0; 23 | } -------------------------------------------------------------------------------- /test/library_checker/range_kth_smallest.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/range_kth_smallest" 2 | 3 | #include "all.hpp" 4 | #include "ds/wavelet_matrix.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | dRV(int, a, n); 9 | Wavelet_Matrix wm(a); 10 | _for (m) { 11 | dR(int, l, r, k); 12 | print(wm.kth(l, r, k)); 13 | } 14 | return 0; 15 | } -------------------------------------------------------------------------------- /test/library_checker/range_set_range_composite.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/range_set_range_composite" 2 | 3 | #include "all.hpp" 4 | #include "ds/range_assignment_segtree.hpp" 5 | #include "monoid/affine.hpp" 6 | #include "modint/montgomery.hpp" 7 | 8 | int main() { 9 | dR(int, n, q); 10 | using mint = MMInt998244353; 11 | using Mono = Monoid_Affine; 12 | Range_Assignment_SegTree seg(n, [&](int) { 13 | dR(mint, a, b); 14 | return std::pair{a, b}; 15 | }); 16 | _for (q) { 17 | dR(int, t); 18 | if (t == 0) { 19 | dR(int, l, r, c, d); 20 | seg.apply(l, r, {c, d}); 21 | } 22 | else { 23 | dR(int, l, r, x); 24 | print(Mono::eval(seg.prod(l, r), x)); 25 | } 26 | } 27 | return 0; 28 | } -------------------------------------------------------------------------------- /test/library_checker/scc.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/scc" 2 | 3 | #include "all.hpp" 4 | #include "graph/strongly_connected_component.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | auto g = read_graph(n, m, 0); 9 | auto [scc, comp] = strongly_connected_component(g); 10 | vvi ans(scc); 11 | _for (i, n) 12 | ans[comp[i]].eb(i); 13 | print(len(ans)); 14 | foreach (x, ans) 15 | print(len(x), x); 16 | return 0; 17 | } -------------------------------------------------------------------------------- /test/library_checker/shift_of_sampling_points_of_polynomial.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/shift_of_sampling_points_of_polynomial" 2 | 3 | #include "all.hpp" 4 | #include "poly/lagrange_interpolate_iota.hpp" 5 | 6 | using mint = MMInt998244353; 7 | int main() { 8 | dR(int, n, m, x); 9 | dRV(mint, a, n); 10 | print(lagrange_interpolate_iota(a, x, m)); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /test/library_checker/shortest_path.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/shortest_path" 2 | 3 | #include "all.hpp" 4 | #include "graph/dijkstra.hpp" 5 | #include "graph/restore_path.hpp" 6 | 7 | int main() { 8 | dR(int, n, m, s, t); 9 | auto g = read_graph(n, m, 0); 10 | auto [dist, par] = dijkstra(g, s); 11 | if (dist[t] == inf) 12 | print(-1); 13 | else { 14 | auto path = restore_path(par, t); 15 | print(dist[t], len(path) - 1); 16 | _for (i, len(path) - 1) 17 | print(path[i], path[i + 1]); 18 | } 19 | return 0; 20 | } -------------------------------------------------------------------------------- /test/library_checker/sort_points_by_argument.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/sort_points_by_argument" 2 | 3 | #include "all.hpp" 4 | 5 | int main() { 6 | dR(int, n); 7 | dRV(pi, a, n); 8 | sort(a, [&](auto&& x, auto&& y) { 9 | return atan2l(x.second, x.first) < atan2l(y.second, y.first); 10 | }); 11 | print(a); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /test/library_checker/sort_points_by_argument_pdqsort.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/sort_points_by_argument" 2 | 3 | #include "all.hpp" 4 | #include "utility/pdqsort.hpp" 5 | 6 | int main() { 7 | dR(int, n); 8 | dRV(pi, a, n); 9 | pdqsort(all(a), [&](auto&& x, auto&& y) { 10 | return atan2l(x.second, x.first) < atan2l(y.second, y.first); 11 | }); 12 | print(a); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /test/library_checker/sqrt_mod.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/sqrt_mod" 2 | 3 | #include "all.hpp" 4 | #include "modint/mod_sqrt.hpp" 5 | 6 | int main() { 7 | multipleTests([&] { 8 | dR(u32, n, p); 9 | auto r = mod_sqrt(n, p); 10 | if (r) 11 | print(*r); 12 | else 13 | print("-1"); 14 | }); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /test/library_checker/static_range_inversions_query.2.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/static_range_inversions_query" 2 | 3 | #include "all.hpp" 4 | #include "ds/offline/mo_dual_offline.hpp" 5 | #include "ds/sqrtfenwicktree.hpp" 6 | #include "monoid/add.hpp" 7 | 8 | int main() { 9 | dR(int, n, q); 10 | dRV(int, a, n); 11 | Mo_Dual_Offline> mo(n); 12 | _for (q) { 13 | dR(int, l, r); 14 | mo.add(l, r); 15 | } 16 | auto b{a}; 17 | UNIQUE(b); 18 | foreach (a, a) 19 | a = LB(b, a); 20 | int m = len(b); 21 | SqrtFenwickTree> ft; 22 | auto add = [&](int i) { ft.multiply(a[i], 1); }; 23 | auto query_l = [&](int i) { return ft.prod(a[i]); }; 24 | auto query_r = [&](int i) { return ft.prod(a[i] + 1, m); }; 25 | auto clear = [&] { ft.build(m); }; 26 | io.displayArray(mo.calc(add, add, query_l, query_r, clear), '\n'); 27 | return 0; 28 | } -------------------------------------------------------------------------------- /test/library_checker/static_range_inversions_query.3.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/static_range_inversions_query" 2 | 3 | #include "all.hpp" 4 | #include "ds/offline/mo_dual_offline.hpp" 5 | #include "ds/sqrtfenwicktree_01.hpp" 6 | 7 | int main() { 8 | dR(int, n, q); 9 | dRV(int, a, n); 10 | Mo_Dual_Offline> mo(n); 11 | _for (q) { 12 | dR(int, l, r); 13 | mo.add(l, r); 14 | } 15 | auto I = argsort(a); 16 | vi b(n); 17 | _for (i, n) 18 | b[I[i]] = i; 19 | a = std::move(b); 20 | SqrtFenwickTree> ft; 21 | auto add = [&](int i) { ft.multiply(a[i], 1); }; 22 | auto query_l = [&](int i) { return ft.prod(a[i]); }; 23 | auto query_r = [&](int i) { return ft.prod(a[i], n); }; 24 | auto clear = [&] { ft.build(n); }; 25 | io.displayArray(mo.calc(add, add, query_l, query_r, clear), '\n'); 26 | return 0; 27 | } -------------------------------------------------------------------------------- /test/library_checker/static_range_sum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/static_range_sum" 2 | 3 | #include "all.hpp" 4 | 5 | int main() { 6 | dR(int, n, q); 7 | dRV(int, a, n); 8 | auto b = cumsum(a); 9 | _for (q) { 10 | dR(int, l, r); 11 | print(b[r] - b[l]); 12 | } 13 | return 0; 14 | } -------------------------------------------------------------------------------- /test/library_checker/staticrmq.dst.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/staticrmq" 2 | 3 | #include "all.hpp" 4 | #include "ds/disjoint_sparse_table.hpp" 5 | #include "monoid/min.hpp" 6 | 7 | int main() { 8 | dR(int, n, m); 9 | Disjoint_Sparse_Table> st(n, [&](int) { return io.read(); }); 10 | _for (m) { 11 | dR(int, l, r); 12 | print(st.prod(l, r)); 13 | } 14 | return 0; 15 | } -------------------------------------------------------------------------------- /test/library_checker/staticrmq.srp.dst.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/staticrmq" 2 | 3 | #include "all.hpp" 4 | #include "ds/disjoint_sparse_table.hpp" 5 | #include "ds/static_range_product.hpp" 6 | #include "monoid/min.hpp" 7 | 8 | int main() { 9 | dR(int, n, m); 10 | Static_Range_Product> st(n, [&](int) { return io.read(); }); 11 | _for (m) { 12 | dR(int, l, r); 13 | print(st.prod(l, r)); 14 | } 15 | return 0; 16 | } -------------------------------------------------------------------------------- /test/library_checker/staticrmq.srp.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/staticrmq" 2 | 3 | #include "all.hpp" 4 | #include "ds/sparse_table.hpp" 5 | #include "ds/static_range_product.hpp" 6 | #include "monoid/min.hpp" 7 | 8 | int main() { 9 | dR(int, n, m); 10 | Static_Range_Product> st(n, [&](int) { return io.read(); }); 11 | _for (m) { 12 | dR(int, l, r); 13 | print(st.prod(l, r)); 14 | } 15 | return 0; 16 | } -------------------------------------------------------------------------------- /test/library_checker/staticrmq.st.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/staticrmq" 2 | 3 | #include "all.hpp" 4 | #include "ds/sparse_table.hpp" 5 | #include "monoid/min.hpp" 6 | 7 | int main() { 8 | dR(int, n, m); 9 | Sparse_Table> st(n, [&](int) { return io.read(); }); 10 | _for (m) { 11 | dR(int, l, r); 12 | print(st.prod(l, r)); 13 | } 14 | return 0; 15 | } -------------------------------------------------------------------------------- /test/library_checker/staticrmq.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/staticrmq" 2 | 3 | #include "all.hpp" 4 | #include "ds/static_rmq.hpp" 5 | #include "monoid/min.hpp" 6 | 7 | int main() { 8 | dR(int, n, m); 9 | Static_RMQ> st(n, [&](int) { return io.read(); }); 10 | _for (m) { 11 | dR(int, l, r); 12 | print(st.prod(l, r)); 13 | } 14 | return 0; 15 | } -------------------------------------------------------------------------------- /test/library_checker/suffixarray.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/suffixarray" 2 | 3 | #include "all.hpp" 4 | #include "string/suffix_array.hpp" 5 | 6 | int main() { 7 | dR(str, s); 8 | Suffix_Array SA(s); 9 | print(SA.sa); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /test/library_checker/tree_diameter.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/tree_diameter" 2 | 3 | #include "all.hpp" 4 | #include "graph/utility.hpp" 5 | 6 | int main() { 7 | dR(int, n); 8 | auto g = read_tree(n, 0); 9 | auto [d, path] = diameter(g); 10 | print(d, len(path)); 11 | print(path); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /test/library_checker/two_edge_connected_components.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/two_edge_connected_components" 2 | 3 | #include "all.hpp" 4 | #include "graph/two_edge_component.hpp" 5 | 6 | int main() { 7 | dR(int, n, m); 8 | auto g = read_graph(n, m, 0); 9 | auto [bcc, comp] = two_edge_component(g); 10 | vvi ans(bcc); 11 | _for (i, n) 12 | ans[comp[i]].eb(i); 13 | print(bcc); 14 | foreach (t, ans) 15 | print(len(t), t); 16 | return 0; 17 | } -------------------------------------------------------------------------------- /test/library_checker/two_sat.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/two_sat" 2 | 3 | #include "all.hpp" 4 | #include "graph/twosat.hpp" 5 | 6 | int main() { 7 | dR(str, p, cnf); 8 | dR(int, n, m); 9 | TwoSat ts(n); 10 | _for (i, m) { 11 | dR(int, a, b, O); 12 | if (a > 0) 13 | a--; 14 | if (b > 0) 15 | b--; 16 | ts.add(a, b); 17 | } 18 | auto values = ts.solve(); 19 | if (!values) { 20 | print("s UNSATISFIABLE"); 21 | } 22 | else { 23 | print("s SATISFIABLE"); 24 | vi ans(n); 25 | _for (i, n) { 26 | if ((*values)[i]) 27 | ans[i] = i + 1; 28 | else 29 | ans[i] = -(i + 1); 30 | } 31 | print("v", ans, 0); 32 | } 33 | return 0; 34 | } -------------------------------------------------------------------------------- /test/library_checker/unionfind.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/unionfind" 2 | 3 | #include "all.hpp" 4 | #include "ds/unionfind.hpp" 5 | 6 | int main() { 7 | dR(int, n, q); 8 | UnionFind uf(n); 9 | _for (q) { 10 | dR(int, t, x, y); 11 | if (t == 0) 12 | uf.merge(x, y); 13 | else 14 | print(uf.same(x, y)); 15 | } 16 | return 0; 17 | } -------------------------------------------------------------------------------- /test/library_checker/vertex_add_path_sum.abelgroup.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/vertex_add_path_sum" 2 | 3 | #include "all.hpp" 4 | #include "graph/tree.hpp" 5 | #include "graph/tree_abelgroup.hpp" 6 | #include "monoid/add.hpp" 7 | 8 | int main() { 9 | dR(int, n, q); 10 | dRV(i64, a, n); 11 | auto g = read_tree(n, 0); 12 | Tree tree(g); 13 | Tree_AbelGroup, false, true, false> st(tree, a); 14 | _for (q) { 15 | dR(int, t, x, y); 16 | if (t == 0) { 17 | st.multiply(x, y); 18 | } 19 | else { 20 | print(st.prod_path(x, y)); 21 | } 22 | } 23 | return 0; 24 | } -------------------------------------------------------------------------------- /test/library_checker/vertex_add_path_sum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/vertex_add_path_sum" 2 | 3 | #include "all.hpp" 4 | #include "graph/tree.hpp" 5 | #include "graph/tree_monoid.hpp" 6 | #include "monoid/add.hpp" 7 | 8 | int main() { 9 | dR(int, n, q); 10 | dRV(i64, a, n); 11 | auto g = read_tree(n, 0); 12 | Tree tree(g); 13 | Tree_Monoid> st(tree, a); 14 | _for (q) { 15 | dR(int, t, x, y); 16 | if (t == 0) { 17 | st.multiply(x, y); 18 | } 19 | else { 20 | print(st.prod_path(x, y)); 21 | } 22 | } 23 | return 0; 24 | } -------------------------------------------------------------------------------- /test/library_checker/vertex_add_range_contour_sum_on_tree.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/vertex_add_range_contour_sum_on_tree" 2 | 3 | #include "all.hpp" 4 | #include "graph/contour_query_range.hpp" 5 | #include "ds/fenwicktree.hpp" 6 | #include "monoid/add.hpp" 7 | 8 | int main() { 9 | dR(int, n, q); 10 | dRV(i64, a, n); 11 | auto g = read_tree(n, 0); 12 | Contour_Query_Range CQ(g); 13 | vc dat(len(CQ)); 14 | _for (i, n) 15 | foreach (p, CQ.get_indices(i)) 16 | dat[p] += a[i]; 17 | FenwickTree> ft(dat); 18 | _for (q) { 19 | dR(int, t); 20 | if (t == 0) { 21 | dR(int, u, x); 22 | a[u] += x; 23 | foreach (p, CQ.get_indices(u)) 24 | ft.multiply(p, x); 25 | } 26 | else { 27 | dR(int, u, l, r); 28 | i64 ans = 0; 29 | if (l <= 0 && 0 < r) 30 | ans += a[u]; 31 | foreach (a, b, CQ.get_contour_range(u, l, r)) 32 | ans += ft.prod(a, b); 33 | print(ans); 34 | } 35 | } 36 | return 0; 37 | } -------------------------------------------------------------------------------- /test/library_checker/vertex_add_subtree_sum.abelgroup.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/vertex_add_subtree_sum" 2 | 3 | #include "all.hpp" 4 | #include "graph/tree.hpp" 5 | #include "graph/tree_abelgroup.hpp" 6 | #include "monoid/add.hpp" 7 | 8 | int main() { 9 | dR(int, n, q); 10 | dRV(i64, a, n); 11 | Graph g(n); 12 | _for (i, 1, n) { 13 | dR(int, p); 14 | g.add(p, i); 15 | } 16 | g.build(); 17 | Tree tree(g); 18 | Tree_AbelGroup, false, false, true> st(tree, a); 19 | _for (q) { 20 | dR(int, t, x); 21 | if (t == 0) { 22 | dR(int, y); 23 | st.multiply(x, y); 24 | } 25 | else { 26 | print(st.prod_subtree(x)); 27 | } 28 | } 29 | return 0; 30 | } -------------------------------------------------------------------------------- /test/library_checker/vertex_add_subtree_sum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/vertex_add_subtree_sum" 2 | 3 | #include "all.hpp" 4 | #include "graph/tree.hpp" 5 | #include "graph/tree_monoid.hpp" 6 | #include "monoid/add.hpp" 7 | 8 | int main() { 9 | dR(int, n, q); 10 | dRV(i64, a, n); 11 | Graph g(n); 12 | _for (i, 1, n) { 13 | dR(int, p); 14 | g.add(p, i); 15 | } 16 | g.build(); 17 | Tree tree(g); 18 | Tree_Monoid> st(tree, a); 19 | _for (q) { 20 | dR(int, t, x); 21 | if (t == 0) { 22 | dR(int, y); 23 | st.multiply(x, y); 24 | } 25 | else { 26 | print(st.prod_subtree(x)); 27 | } 28 | } 29 | return 0; 30 | } -------------------------------------------------------------------------------- /test/library_checker/vertex_get_range_contour_add_on_tree.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/vertex_get_range_contour_add_on_tree" 2 | 3 | #include "all.hpp" 4 | #include "graph/contour_query_range.hpp" 5 | #include "ds/fenwicktree.hpp" 6 | #include "monoid/add.hpp" 7 | 8 | int main() { 9 | dR(int, n, q); 10 | dRV(i64, a, n); 11 | auto g = read_tree(n, 0); 12 | Contour_Query_Range CQ(g); 13 | FenwickTree> ft(len(CQ) + 1); 14 | _for (q) { 15 | dR(int, t); 16 | if (t == 0) { 17 | dR(int, u, l, r, x); 18 | foreach (a, b, CQ.get_contour_range(u, l, r)) 19 | ft.multiply(a, x), ft.multiply(b, -x); 20 | if (l <= 0 && 0 < r) 21 | a[u] += x; 22 | } 23 | else { 24 | dR(int, u); 25 | i64 ans = a[u]; 26 | foreach (p, CQ.get_indices(u)) 27 | ans += ft.prod(p + 1); 28 | print(ans); 29 | } 30 | } 31 | return 0; 32 | } -------------------------------------------------------------------------------- /test/library_checker/vertex_set_path_composite.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/vertex_set_path_composite" 2 | 3 | #include "all.hpp" 4 | #include "graph/tree.hpp" 5 | #include "graph/tree_monoid.hpp" 6 | #include "modint/montgomery.hpp" 7 | #include "monoid/affine.hpp" 8 | 9 | int main() { 10 | using mint = MMInt998244353; 11 | using Mono = Monoid_Affine; 12 | dR(int, n, q); 13 | dRV(Mono::X, a, n); 14 | auto g = read_tree(n, 0); 15 | Tree tree(g); 16 | Tree_Monoid st(tree, a); 17 | _for (q) { 18 | dR(int, t, x, y, z); 19 | if (t == 0) { 20 | st.set(x, {y, z}); 21 | } 22 | else { 23 | print(Mono::eval(st.prod_path(x, y), z)); 24 | } 25 | } 26 | return 0; 27 | } -------------------------------------------------------------------------------- /test/library_checker/wildcard_pattern_matching.avx2.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/wildcard_pattern_matching" 2 | 3 | #include "all.hpp" 4 | #include "poly/ntt_avx2.hpp" 5 | #include "string/wildcard_pattern_matching.hpp" 6 | 7 | int main() { 8 | dR(str, s, t); 9 | foreach (x, wildcard_pattern_matching(s, t, '*')) 10 | io.putch('0' + x); 11 | print(); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /test/library_checker/wildcard_pattern_matching.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/wildcard_pattern_matching" 2 | 3 | #include "all.hpp" 4 | #include "string/wildcard_pattern_matching.hpp" 5 | 6 | int main() { 7 | dR(str, s, t); 8 | foreach (x, wildcard_pattern_matching(s, t, '*')) 9 | io.putch('0' + x); 10 | print(); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /test/library_checker/zalgorithm.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/zalgorithm" 2 | 3 | #include "all.hpp" 4 | #include "string/zalgorithm.hpp" 5 | 6 | int main() { 7 | dR(str, s); 8 | print(zalgorithm(s)); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /test/library_checker/zalgorithm_rolling_hash.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/zalgorithm" 2 | 3 | #include "all.hpp" 4 | #include "string/rolling_hash.hpp" 5 | 6 | int main() { 7 | dR(str, s); 8 | Rollinghash hash(s); 9 | _for (i, len(s)) { 10 | io.write(hash.lcp(hash, 0, len(s), hash, i, len(s)), ' '); 11 | } 12 | print(); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /timer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef CPH 3 | #include 4 | #include 5 | 6 | struct AutoTimer { 7 | clock_t begin; 8 | AutoTimer(): begin(clock()) {} 9 | ~AutoTimer() { 10 | double t = (clock() - begin) * 1000. / CLOCKS_PER_SEC; 11 | fprintf(stderr, "\033[1;32m"); 12 | if (t >= 60000) 13 | fprintf(stderr, "%.2lfmin\n", t / 60000.); 14 | else if (t >= 1000) 15 | fprintf(stderr, "%.2lfs\n", t / 1000.); 16 | else 17 | fprintf(stderr, "%.0lfms\n", t); 18 | fprintf(stderr, "\033[0m"); 19 | } 20 | } _auto_timer; 21 | #endif -------------------------------------------------------------------------------- /utility/cache.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ds/hashmap.hpp" 3 | 4 | // https://codeforces.com/blog/entry/124683 5 | template 6 | struct Cache; 7 | template 8 | struct Cache: F { 9 | HashMap, R> mp; 10 | explicit Cache(const F& f): F(f) {} 11 | R operator()(auto&&... args) { 12 | auto t = std::tuple{FORWARD(args)...}; 13 | if (mp.contains(t)) 14 | return mp[t]; 15 | return mp[t] = F::operator()(*this, FORWARD(args)...); 16 | } 17 | }; 18 | template 19 | auto use_cache(const auto& f) { return Cache()...))(Args...), std::decay_t>(f); } -------------------------------------------------------------------------------- /utility/interval_union.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | vc> interval_union(vc> a) { 6 | if (a.empty()) 7 | return {}; 8 | sort(a); 9 | vc> b; 10 | T l = -inf, r = -inf; 11 | foreach (x, y, a) 12 | if (x > r) { 13 | if (l != -inf) 14 | b.eb(l, r); 15 | l = x, r = y; 16 | } 17 | else 18 | chkmax(r, y); 19 | b.eb(l, r); 20 | return b; 21 | } -------------------------------------------------------------------------------- /utility/itos_table.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | constexpr auto itos_table = [] { 5 | std::array O; 6 | char* p = O.data(); 7 | _for (i, 10) 8 | _for (j, 10) 9 | _for (k, 10) 10 | _for (l, 10) 11 | *p++ = 48 + i, *p++ = 48 + j, *p++ = 48 + k, *p++ = 48 + l; 12 | return O; 13 | }(); -------------------------------------------------------------------------------- /utility/make_double_width.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct make_double_width {}; 6 | template <> 7 | struct make_double_width { 8 | using type = u16; 9 | }; 10 | template <> 11 | struct make_double_width { 12 | using type = u32; 13 | }; 14 | template <> 15 | struct make_double_width { 16 | using type = u64; 17 | }; 18 | template <> 19 | struct make_double_width { 20 | using type = u128; 21 | }; 22 | template 23 | using make_double_width_t = make_double_width::type; -------------------------------------------------------------------------------- /utility/memory_pool.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | template 5 | struct Memory_Pool { 6 | T* pool; 7 | int id = 0; 8 | Memory_Pool(): pool(new T[N]) {} 9 | int size() const { return id; } 10 | T* new_node(T x = {}) { 11 | pool[id] = std::move(x); 12 | return &pool[id++]; 13 | } 14 | int new_node_id(T x = {}) { 15 | pool[id] = std::move(x); 16 | return id++; 17 | } 18 | T& operator[](int i) { return pool[i]; } 19 | const T& operator[](int i) const { return pool[i]; } 20 | }; 21 | template 22 | struct Memory_Pool { 23 | std::deque pool; 24 | int size() const { return len(pool); } 25 | T* new_node(T x = {}) { return &pool.eb(std::move(x)); } 26 | int new_node_id(T x = {}) { 27 | pool.eb(std::move(x)); 28 | return size() - 1; 29 | } 30 | T& operator[](int i) { return pool[i]; } 31 | const T& operator[](int i) const { return pool[i]; } 32 | }; -------------------------------------------------------------------------------- /utility/pbds.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace pbds { 6 | using namespace __gnu_pbds; 7 | template 8 | using unordered_map = gp_hash_table, direct_mask_range_hashing<>, linear_probe_fn<>, 9 | hash_standard_resize_policy, hash_load_check_resize_trigger<>, true>>; 10 | template 11 | using unordered_set = unordered_map; 12 | template > 13 | using map = tree; 14 | template > 15 | using multimap = tree; 16 | template > 17 | using set = map; 18 | template > 19 | using multiset = multimap; 20 | } // namespace pbds -------------------------------------------------------------------------------- /utility/timer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "template.hpp" 3 | 4 | struct Timer { 5 | std::chrono::high_resolution_clock::time_point st; 6 | 7 | Timer() { reset(); } 8 | void reset() { st = std::chrono::high_resolution_clock::now(); } 9 | 10 | auto operator()() const { 11 | auto ed = std::chrono::high_resolution_clock::now(); 12 | return ed - st; 13 | } 14 | auto us() const { return std::chrono::duration_cast(operator()()).count(); } 15 | auto ms() const { return std::chrono::duration_cast(operator()()).count(); } 16 | auto s() const { return std::chrono::duration_cast(operator()()).count(); } 17 | }; --------------------------------------------------------------------------------