├── test ├── graphs │ ├── dijkstra │ │ ├── train │ │ │ ├── tests │ │ │ │ ├── sample1.out │ │ │ │ ├── sample2.out │ │ │ │ ├── sample3.out │ │ │ │ ├── sample4.out │ │ │ │ ├── sample3.in │ │ │ │ ├── sample1.in │ │ │ │ ├── sample2.in │ │ │ │ └── sample4.in │ │ │ └── train.cpp │ │ └── shortest_path │ │ │ ├── tests │ │ │ ├── sample2.out │ │ │ ├── sample2.in │ │ │ ├── sample1.out │ │ │ └── sample1.in │ │ │ └── shortest_path.cpp │ ├── two_sat │ │ └── two_sat │ │ │ ├── tests │ │ │ ├── sample2.out │ │ │ ├── sample1.out │ │ │ ├── sample2.in │ │ │ └── sample1.in │ │ │ └── two_sat.cpp │ ├── tree │ │ └── weighted_tree_diameter │ │ │ ├── tests │ │ │ ├── sample1.out │ │ │ └── sample1.in │ │ │ └── weighted_tree_diameter.cpp │ ├── lowest_common_ancestor │ │ └── lowest_common_ancestor │ │ │ ├── tests │ │ │ ├── sample1.out │ │ │ └── sample1.in │ │ │ └── lowest_common_ancestor.cpp │ └── heavy_path_decomposition │ │ └── vertex_add_path_sum │ │ ├── tests │ │ ├── sample1.out │ │ └── sample1.in │ │ └── vertex_add_path_sum.cpp ├── strings │ ├── z_algorithm │ │ └── z_algorithm │ │ │ ├── tests │ │ │ ├── sample4.in │ │ │ ├── sample1.in │ │ │ ├── sample3.in │ │ │ ├── sample4.out │ │ │ ├── sample1.out │ │ │ ├── sample2.in │ │ │ ├── sample3.out │ │ │ └── sample2.out │ │ │ └── z_algorithm.cpp │ ├── polynomial_hash │ │ └── good_substrings │ │ │ ├── tests │ │ │ ├── sample1.out │ │ │ ├── sample2.out │ │ │ ├── sample1.in │ │ │ └── sample2.in │ │ │ └── good_substrings.cpp │ ├── suffix_array │ │ ├── suffix_array │ │ │ ├── tests │ │ │ │ ├── sample1.in │ │ │ │ ├── sample4.in │ │ │ │ ├── sample2.in │ │ │ │ ├── sample3.in │ │ │ │ ├── sample4.out │ │ │ │ ├── sample1.out │ │ │ │ ├── sample3.out │ │ │ │ └── sample2.out │ │ │ └── suffix_array.cpp │ │ └── count_distinct_substrings │ │ │ ├── tests │ │ │ ├── sample1.out │ │ │ ├── sample2.out │ │ │ ├── sample3.out │ │ │ ├── sample4.in │ │ │ ├── sample4.out │ │ │ ├── sample1.in │ │ │ ├── sample3.in │ │ │ └── sample2.in │ │ │ └── count_distinct_substrings.cpp │ ├── palindromes │ │ └── enumerate_palindromes │ │ │ ├── tests │ │ │ ├── sample4.in │ │ │ ├── sample1.in │ │ │ ├── sample3.in │ │ │ ├── sample2.in │ │ │ ├── sample4.out │ │ │ ├── sample1.out │ │ │ ├── sample3.out │ │ │ └── sample2.out │ │ │ └── enumerate_palindromes.cpp │ ├── suffix_automaton │ │ └── count_distinct_substrings │ │ │ ├── tests │ │ │ ├── sample1.out │ │ │ ├── sample2.out │ │ │ ├── sample3.out │ │ │ ├── sample4.in │ │ │ ├── sample4.out │ │ │ ├── sample1.in │ │ │ ├── sample2.in │ │ │ └── sample3.in │ │ │ └── count_distinct_substrings.cpp │ ├── mutable_string │ │ └── count_matches_in_mutable_text │ │ │ ├── tests │ │ │ ├── sample1.out │ │ │ ├── sample2.out │ │ │ ├── sample1.in │ │ │ └── sample2.in │ │ │ └── count_matches_in_mutable_text.cpp │ ├── mutable_string_bitset │ │ └── count_matches_in_mutable_text │ │ │ ├── tests │ │ │ ├── sample1.out │ │ │ ├── sample2.out │ │ │ ├── sample1.in │ │ │ └── sample2.in │ │ │ └── count_matches_in_mutable_text.cpp │ ├── knuth_morris_pratt │ │ └── pattern_find │ │ │ ├── tests │ │ │ ├── sample1.in │ │ │ └── sample1.out │ │ │ └── pattern_find.cpp │ └── trie │ │ └── minimum_length_substring_with_k_occurrences │ │ ├── tests │ │ ├── sample1.out │ │ ├── sample2.out │ │ ├── sample1.in │ │ └── sample2.in │ │ └── minimum_length_substring_with_k_occurrences.cpp ├── misc │ ├── subset_sum │ │ └── polandball_and_gifts │ │ │ ├── tests │ │ │ ├── sample1.out │ │ │ ├── sample2.out │ │ │ ├── sample1.in │ │ │ └── sample2.in │ │ │ └── polandball_and_gifts.cpp │ └── count_distinct_in_range │ │ ├── range_set_query │ │ ├── tests │ │ │ ├── sample1.out │ │ │ ├── sample1.in │ │ │ ├── sample2.out │ │ │ └── sample2.in │ │ └── range_set_query.cpp │ │ └── army_creation │ │ ├── tests │ │ ├── sample1.out │ │ └── sample1.in │ │ └── army_creation.cpp ├── numeric │ ├── ntt │ │ └── convolution_mod_998244353 │ │ │ ├── tests │ │ │ ├── sample2.out │ │ │ ├── sample1.out │ │ │ ├── sample1.in │ │ │ ├── sample2.in │ │ │ ├── sample3.out │ │ │ └── sample3.in │ │ │ └── convolution_mod_998244353.cpp │ ├── bignum_addpow2_compare │ │ └── the_classic_problem │ │ │ ├── tests │ │ │ ├── sample3.out │ │ │ ├── sample1.out │ │ │ ├── sample2.out │ │ │ ├── sample3.in │ │ │ ├── sample2.in │ │ │ └── sample1.in │ │ │ └── the_classic_problem.cpp │ ├── complex_fft │ │ └── convolution_mod_1000000007 │ │ │ ├── tests │ │ │ ├── sample2.out │ │ │ ├── sample1.out │ │ │ ├── sample1.in │ │ │ ├── sample2.in │ │ │ ├── sample3.out │ │ │ └── sample3.in │ │ │ └── convolution_mod_1000000007.cpp │ ├── modnum │ │ └── exponentiation │ │ │ ├── tests │ │ │ ├── sample1.in │ │ │ └── sample1.out │ │ │ └── exponentiation.cpp │ ├── tonelli-shanks │ │ └── sqrt_mod │ │ │ ├── tests │ │ │ ├── sample1.out │ │ │ └── sample1.in │ │ │ └── sqrt_mod.cpp │ └── discrete_logarithm │ │ └── discrete_logarithm │ │ ├── tests │ │ ├── sample1.out │ │ └── sample1.in │ │ └── discrete_logarithm.cpp └── data_structures │ ├── segment_tree_searchable │ └── deda │ │ ├── tests │ │ ├── sample1.out │ │ ├── sample2.out │ │ ├── sample1.in │ │ └── sample2.in │ │ └── deda.cpp │ ├── union_find │ └── roads_not_only_in_berland │ │ ├── tests │ │ ├── sample1.out │ │ ├── sample1.in │ │ ├── sample2.out │ │ └── sample2.in │ │ └── roads_not_only_in_berland.cpp │ ├── line_container │ └── escape_through_leaf │ │ ├── tests │ │ ├── sample1.out │ │ ├── sample2.out │ │ ├── sample1.in │ │ └── sample2.in │ │ └── escape_through_leaf.cpp │ ├── line_container_monotonic │ ├── cats_transport │ │ ├── tests │ │ │ ├── sample1.out │ │ │ └── sample1.in │ │ └── cats_transport.cpp │ └── the_fair_nut_and_rectangles │ │ ├── tests │ │ ├── sample1.out │ │ ├── sample2.out │ │ ├── sample3.out │ │ ├── sample1.in │ │ ├── sample2.in │ │ └── sample3.in │ │ └── the_fair_nut_and_rectangles.cpp │ ├── segment_tree_persistent │ └── k-query │ │ ├── tests │ │ ├── sample1.out │ │ └── sample1.in │ │ └── k-query.cpp │ ├── segment_tree │ ├── distinct_characters_queries │ │ ├── tests │ │ │ ├── sample1.out │ │ │ ├── sample2.out │ │ │ ├── sample1.in │ │ │ └── sample2.in │ │ └── distinct_characters_queries.cpp │ ├── point_add_range_sum │ │ ├── tests │ │ │ ├── sample1.my │ │ │ ├── sample1.out │ │ │ └── sample1.in │ │ └── point_add_range_sum.cpp │ └── point_set_range_composite │ │ ├── tests │ │ ├── sample1.my │ │ ├── sample1.out │ │ └── sample1.in │ │ └── point_set_range_composite.cpp │ ├── segment_tree_lazy │ └── range_add_range_min │ │ ├── tests │ │ ├── sample1.out │ │ └── sample1.in │ │ └── range_add_range_min.cpp │ ├── static_to_dynamic_transformation │ └── string_set_queries │ │ ├── tests │ │ ├── sample1.out │ │ ├── sample2.out │ │ ├── sample1.in │ │ └── sample2.in │ │ └── string_set_queries.cpp │ ├── binary_indexed_tree │ └── point_add_range_sum │ │ ├── tests │ │ ├── sample1.out │ │ └── sample1.in │ │ └── point_add_range_sum.cpp │ ├── union_find_rewindable │ └── connect_and_disconnect │ │ ├── tests │ │ ├── sample1.out │ │ └── sample1.in │ │ └── connect_and_disconnect.cpp │ ├── sqrt_decomposition_point_query │ └── duff_is_mad │ │ ├── tests │ │ ├── sample1.out │ │ └── sample1.in │ │ └── duff_is_mad.cpp │ ├── union_find_bipartite │ └── prefix_enlightenment │ │ ├── tests │ │ ├── sample3.out │ │ ├── sample1.out │ │ ├── sample2.out │ │ ├── sample3.in │ │ ├── sample1.in │ │ ├── sample2.in │ │ ├── sample4.in │ │ └── sample4.out │ │ └── prefix_enlightenment.cpp │ └── sparse_table │ └── static_rmq │ ├── tests │ ├── sample1.out │ └── sample1.in │ └── static_rmq.cpp ├── .circleci ├── util.py ├── run_tests.py └── expand_dependencies.py ├── graphs ├── maximum_matching.cpp ├── topological_sort.cpp ├── graph.cpp ├── strongly_connected_components.cpp ├── digraph_reachability.cpp ├── breadth_first_search.cpp ├── poset_width.cpp ├── bipartite_graph.cpp ├── chain_decomposition.cpp ├── lca_jump_pointers.cpp ├── lowest_common_ancestor.cpp ├── condensed_tree.cpp ├── dinic.cpp ├── two_sat.cpp ├── tree_isomorphism.cpp ├── centroid_decomposition.cpp ├── dijkstra.cpp └── min_cost_flow.cpp ├── strings ├── z_algorithm.cpp ├── mutable_string_bitset.cpp ├── palindromes.cpp ├── knuth_morris_pratt.cpp ├── mutable_string.cpp └── polynomial_hash.cpp ├── data_structures ├── line.cpp ├── monotonic_stack.cpp ├── static_to_dynamic_transformation.cpp ├── splitmix64_hash_map.cpp ├── monotonic_queue.cpp ├── sparse_table.cpp ├── segment_tree.cpp ├── union_find.cpp ├── sqrt_decomposition_point_query.cpp ├── line_container.cpp ├── segment_tree_searchable.cpp ├── line_container_monotonic.cpp ├── binary_indexed_tree.cpp ├── segment_tree_persistent.cpp └── segment_tree_lazy.cpp ├── misc ├── subset_sum.cpp ├── stable_counting_sort.cpp └── count_distinct_in_range.cpp └── numeric ├── garner.cpp ├── berlekamp-massey.cpp ├── fft.cpp ├── tonelli-shanks.cpp ├── ntt.cpp ├── bitwise_convolution.cpp ├── discrete_logarithm.cpp ├── karatsuba.cpp ├── sieve.cpp ├── matrix_array.cpp ├── frac.cpp ├── matrix.cpp └── bignum_addpow2_compare.cpp /test/graphs/dijkstra/train/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /test/graphs/dijkstra/train/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 5 2 | -------------------------------------------------------------------------------- /test/graphs/dijkstra/train/tests/sample3.out: -------------------------------------------------------------------------------- 1 | -1 2 | -------------------------------------------------------------------------------- /test/graphs/dijkstra/train/tests/sample4.out: -------------------------------------------------------------------------------- 1 | 26 2 | -------------------------------------------------------------------------------- /test/graphs/dijkstra/shortest_path/tests/sample2.out: -------------------------------------------------------------------------------- 1 | -1 2 | -------------------------------------------------------------------------------- /test/graphs/dijkstra/train/tests/sample3.in: -------------------------------------------------------------------------------- 1 | 3 0 3 1 2 | 3 | -------------------------------------------------------------------------------- /test/strings/z_algorithm/z_algorithm/tests/sample4.in: -------------------------------------------------------------------------------- 1 | aaaaa 2 | -------------------------------------------------------------------------------- /test/graphs/two_sat/two_sat/tests/sample2.out: -------------------------------------------------------------------------------- 1 | s UNSATISFIABLE 2 | -------------------------------------------------------------------------------- /test/misc/subset_sum/polandball_and_gifts/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 2 4 2 | -------------------------------------------------------------------------------- /test/misc/subset_sum/polandball_and_gifts/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 2 2 2 | -------------------------------------------------------------------------------- /test/strings/polynomial_hash/good_substrings/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 5 2 | -------------------------------------------------------------------------------- /test/strings/polynomial_hash/good_substrings/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 8 2 | -------------------------------------------------------------------------------- /test/strings/suffix_array/suffix_array/tests/sample1.in: -------------------------------------------------------------------------------- 1 | abcbcba 2 | -------------------------------------------------------------------------------- /test/strings/suffix_array/suffix_array/tests/sample4.in: -------------------------------------------------------------------------------- 1 | aaaaa 2 | -------------------------------------------------------------------------------- /test/strings/z_algorithm/z_algorithm/tests/sample1.in: -------------------------------------------------------------------------------- 1 | abcbcba 2 | -------------------------------------------------------------------------------- /test/strings/z_algorithm/z_algorithm/tests/sample3.in: -------------------------------------------------------------------------------- 1 | ababacaca 2 | -------------------------------------------------------------------------------- /test/strings/z_algorithm/z_algorithm/tests/sample4.out: -------------------------------------------------------------------------------- 1 | 5 4 3 2 1 2 | -------------------------------------------------------------------------------- /test/strings/palindromes/enumerate_palindromes/tests/sample4.in: -------------------------------------------------------------------------------- 1 | aaaaa 2 | -------------------------------------------------------------------------------- /test/strings/suffix_array/suffix_array/tests/sample2.in: -------------------------------------------------------------------------------- 1 | mississippi 2 | -------------------------------------------------------------------------------- /test/strings/suffix_array/suffix_array/tests/sample3.in: -------------------------------------------------------------------------------- 1 | ababacaca 2 | -------------------------------------------------------------------------------- /test/strings/suffix_array/suffix_array/tests/sample4.out: -------------------------------------------------------------------------------- 1 | 4 3 2 1 0 2 | -------------------------------------------------------------------------------- /test/strings/z_algorithm/z_algorithm/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 7 0 0 0 0 0 1 2 | -------------------------------------------------------------------------------- /test/strings/z_algorithm/z_algorithm/tests/sample2.in: -------------------------------------------------------------------------------- 1 | mississippi 2 | -------------------------------------------------------------------------------- /test/graphs/dijkstra/shortest_path/tests/sample2.in: -------------------------------------------------------------------------------- 1 | 2 1 0 1 2 | 1 0 10 3 | -------------------------------------------------------------------------------- /test/graphs/tree/weighted_tree_diameter/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 15 4 2 | 5 1 2 6 3 | -------------------------------------------------------------------------------- /test/numeric/ntt/convolution_mod_998244353/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 871938225 2 | -------------------------------------------------------------------------------- /test/strings/palindromes/enumerate_palindromes/tests/sample1.in: -------------------------------------------------------------------------------- 1 | abcbcba 2 | -------------------------------------------------------------------------------- /test/strings/palindromes/enumerate_palindromes/tests/sample3.in: -------------------------------------------------------------------------------- 1 | ababacaca 2 | -------------------------------------------------------------------------------- /test/strings/suffix_array/count_distinct_substrings/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 21 2 | -------------------------------------------------------------------------------- /test/strings/suffix_array/count_distinct_substrings/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 53 2 | -------------------------------------------------------------------------------- /test/strings/suffix_array/count_distinct_substrings/tests/sample3.out: -------------------------------------------------------------------------------- 1 | 33 2 | -------------------------------------------------------------------------------- /test/strings/suffix_array/count_distinct_substrings/tests/sample4.in: -------------------------------------------------------------------------------- 1 | aaaaa 2 | -------------------------------------------------------------------------------- /test/strings/suffix_array/count_distinct_substrings/tests/sample4.out: -------------------------------------------------------------------------------- 1 | 5 2 | -------------------------------------------------------------------------------- /test/strings/suffix_array/suffix_array/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 6 0 5 3 1 4 2 2 | -------------------------------------------------------------------------------- /test/strings/suffix_array/suffix_array/tests/sample3.out: -------------------------------------------------------------------------------- 1 | 8 0 2 6 4 1 3 7 5 2 | -------------------------------------------------------------------------------- /test/strings/z_algorithm/z_algorithm/tests/sample3.out: -------------------------------------------------------------------------------- 1 | 9 0 3 0 1 0 1 0 1 2 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree_searchable/deda/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 3 2 | 1 3 | -------------------------------------------------------------------------------- /test/data_structures/union_find/roads_not_only_in_berland/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/graphs/two_sat/two_sat/tests/sample1.out: -------------------------------------------------------------------------------- 1 | s SATISFIABLE 2 | v -1 2 -3 4 5 0 3 | -------------------------------------------------------------------------------- /test/misc/subset_sum/polandball_and_gifts/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 5 2 2 | 3 4 1 5 2 3 | -------------------------------------------------------------------------------- /test/numeric/bignum_addpow2_compare/the_classic_problem/tests/sample3.out: -------------------------------------------------------------------------------- 1 | -1 2 | -------------------------------------------------------------------------------- /test/numeric/complex_fft/convolution_mod_1000000007/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 999300007 2 | -------------------------------------------------------------------------------- /test/strings/palindromes/enumerate_palindromes/tests/sample2.in: -------------------------------------------------------------------------------- 1 | mississippi 2 | -------------------------------------------------------------------------------- /test/strings/suffix_array/count_distinct_substrings/tests/sample1.in: -------------------------------------------------------------------------------- 1 | abcbcba 2 | -------------------------------------------------------------------------------- /test/strings/suffix_array/count_distinct_substrings/tests/sample3.in: -------------------------------------------------------------------------------- 1 | ababacaca 2 | -------------------------------------------------------------------------------- /test/strings/suffix_array/suffix_array/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 10 7 4 1 0 9 8 6 3 5 2 2 | -------------------------------------------------------------------------------- /test/strings/suffix_automaton/count_distinct_substrings/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 21 2 | -------------------------------------------------------------------------------- /test/strings/suffix_automaton/count_distinct_substrings/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 53 2 | -------------------------------------------------------------------------------- /test/strings/suffix_automaton/count_distinct_substrings/tests/sample3.out: -------------------------------------------------------------------------------- 1 | 33 2 | -------------------------------------------------------------------------------- /test/strings/suffix_automaton/count_distinct_substrings/tests/sample4.in: -------------------------------------------------------------------------------- 1 | aaaaa 2 | -------------------------------------------------------------------------------- /test/strings/suffix_automaton/count_distinct_substrings/tests/sample4.out: -------------------------------------------------------------------------------- 1 | 5 2 | -------------------------------------------------------------------------------- /test/strings/z_algorithm/z_algorithm/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 11 0 0 0 0 0 0 0 0 0 0 2 | -------------------------------------------------------------------------------- /test/data_structures/line_container/escape_through_leaf/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 10 50 0 2 | -------------------------------------------------------------------------------- /test/data_structures/line_container_monotonic/cats_transport/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 3 2 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree_persistent/k-query/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 2 2 | 0 3 | 3 4 | -------------------------------------------------------------------------------- /test/data_structures/union_find/roads_not_only_in_berland/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 2 2 | 1 2 3 | -------------------------------------------------------------------------------- /test/graphs/dijkstra/shortest_path/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 11 3 2 | 2 1 3 | 1 0 4 | 0 3 5 | -------------------------------------------------------------------------------- /test/graphs/dijkstra/train/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 3 2 1 3 2 | 1 2 2 3 3 | 2 3 3 4 4 | 5 | -------------------------------------------------------------------------------- /test/graphs/dijkstra/train/tests/sample2.in: -------------------------------------------------------------------------------- 1 | 3 2 3 1 2 | 1 2 2 3 3 | 2 3 3 4 4 | 5 | -------------------------------------------------------------------------------- /test/misc/count_distinct_in_range/range_set_query/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 2 2 | 3 3 | 1 4 | -------------------------------------------------------------------------------- /test/numeric/modnum/exponentiation/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 3 2 | 3 7 1 3 | 15 2 2 4 | 3 4 5 5 | -------------------------------------------------------------------------------- /test/numeric/modnum/exponentiation/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 2187 2 | 50625 3 | 763327764 4 | -------------------------------------------------------------------------------- /test/numeric/ntt/convolution_mod_998244353/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 5 16 34 60 70 70 59 36 2 | -------------------------------------------------------------------------------- /test/numeric/tonelli-shanks/sqrt_mod/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 0 2 | 1 3 | -1 4 | -1 5 | 3 6 | -------------------------------------------------------------------------------- /test/strings/mutable_string/count_matches_in_mutable_text/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 3 2 | 1 3 | -------------------------------------------------------------------------------- /test/strings/palindromes/enumerate_palindromes/tests/sample4.out: -------------------------------------------------------------------------------- 1 | 1 2 3 4 5 4 3 2 1 2 | -------------------------------------------------------------------------------- /test/strings/suffix_array/count_distinct_substrings/tests/sample2.in: -------------------------------------------------------------------------------- 1 | mississippi 2 | -------------------------------------------------------------------------------- /test/strings/suffix_automaton/count_distinct_substrings/tests/sample1.in: -------------------------------------------------------------------------------- 1 | abcbcba 2 | -------------------------------------------------------------------------------- /test/strings/suffix_automaton/count_distinct_substrings/tests/sample2.in: -------------------------------------------------------------------------------- 1 | mississippi 2 | -------------------------------------------------------------------------------- /test/strings/suffix_automaton/count_distinct_substrings/tests/sample3.in: -------------------------------------------------------------------------------- 1 | ababacaca 2 | -------------------------------------------------------------------------------- /test/data_structures/line_container/escape_through_leaf/tests/sample2.out: -------------------------------------------------------------------------------- 1 | -300 100 0 0 2 | -------------------------------------------------------------------------------- /test/data_structures/union_find/roads_not_only_in_berland/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 1 2 | 3 1 1 4 3 | -------------------------------------------------------------------------------- /test/misc/subset_sum/polandball_and_gifts/tests/sample2.in: -------------------------------------------------------------------------------- 1 | 10 1 2 | 2 3 4 5 6 7 8 9 10 1 3 | -------------------------------------------------------------------------------- /test/numeric/ntt/convolution_mod_998244353/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 4 5 2 | 1 2 3 4 3 | 5 6 7 8 9 4 | -------------------------------------------------------------------------------- /test/numeric/ntt/convolution_mod_998244353/tests/sample2.in: -------------------------------------------------------------------------------- 1 | 1 1 2 | 10000000 3 | 10000000 4 | -------------------------------------------------------------------------------- /test/strings/mutable_string/count_matches_in_mutable_text/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 2 2 | 2 3 | 1 4 | -------------------------------------------------------------------------------- /test/data_structures/line_container_monotonic/the_fair_nut_and_rectangles/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /test/data_structures/line_container_monotonic/the_fair_nut_and_rectangles/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /test/data_structures/line_container_monotonic/the_fair_nut_and_rectangles/tests/sample3.out: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree/distinct_characters_queries/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 3 2 | 1 3 | 2 4 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree/point_add_range_sum/tests/sample1.my: -------------------------------------------------------------------------------- 1 | 15 2 | 7 3 | 25 4 | 6 5 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree/point_add_range_sum/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 15 2 | 7 3 | 25 4 | 6 5 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree_lazy/range_add_range_min/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 1 2 | 0 3 | 0 4 | -------------------------------------------------------------------------------- /test/misc/count_distinct_in_range/army_creation/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 2 2 | 4 3 | 1 4 | 3 5 | 2 6 | -------------------------------------------------------------------------------- /test/numeric/bignum_addpow2_compare/the_classic_problem/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 3 2 | 4 3 | 1 2 3 4 4 | -------------------------------------------------------------------------------- /test/numeric/complex_fft/convolution_mod_1000000007/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 5 16 34 60 70 70 59 36 2 | -------------------------------------------------------------------------------- /test/strings/mutable_string_bitset/count_matches_in_mutable_text/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 3 2 | 1 3 | -------------------------------------------------------------------------------- /test/strings/palindromes/enumerate_palindromes/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 1 0 1 0 3 0 7 0 3 0 1 0 1 2 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree_searchable/deda/tests/sample2.out: -------------------------------------------------------------------------------- 1 | -1 2 | -1 3 | 3 4 | 2 5 | 9 6 | -------------------------------------------------------------------------------- /test/data_structures/static_to_dynamic_transformation/string_set_queries/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 2 2 | 2 3 | -------------------------------------------------------------------------------- /test/graphs/two_sat/two_sat/tests/sample2.in: -------------------------------------------------------------------------------- 1 | p cnf 2 4 2 | 1 2 0 3 | 1 -2 0 4 | -1 2 0 5 | -1 -2 0 6 | -------------------------------------------------------------------------------- /test/numeric/bignum_addpow2_compare/the_classic_problem/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 112 2 | 4 3 | 1 2 3 4 4 | -------------------------------------------------------------------------------- /test/numeric/complex_fft/convolution_mod_1000000007/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 4 5 2 | 1 2 3 4 3 | 5 6 7 8 9 4 | -------------------------------------------------------------------------------- /test/numeric/complex_fft/convolution_mod_1000000007/tests/sample2.in: -------------------------------------------------------------------------------- 1 | 1 1 2 | 10000000 3 | 10000000 4 | -------------------------------------------------------------------------------- /test/numeric/tonelli-shanks/sqrt_mod/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 5 2 | 0 5 3 | 1 5 4 | 2 5 5 | 3 5 6 | 4 5 7 | -------------------------------------------------------------------------------- /test/strings/mutable_string_bitset/count_matches_in_mutable_text/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 2 2 | 2 3 | 1 4 | -------------------------------------------------------------------------------- /test/strings/palindromes/enumerate_palindromes/tests/sample3.out: -------------------------------------------------------------------------------- 1 | 1 0 3 0 5 0 3 0 1 0 3 0 5 0 3 0 1 2 | -------------------------------------------------------------------------------- /test/data_structures/binary_indexed_tree/point_add_range_sum/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 15 2 | 7 3 | 25 4 | 6 5 | -------------------------------------------------------------------------------- /test/data_structures/union_find_rewindable/connect_and_disconnect/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 5 2 | 1 3 | 1 4 | 2 5 | -------------------------------------------------------------------------------- /test/graphs/lowest_common_ancestor/lowest_common_ancestor/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | 0 4 | 2 5 | 2 6 | -------------------------------------------------------------------------------- /test/numeric/bignum_addpow2_compare/the_classic_problem/tests/sample3.in: -------------------------------------------------------------------------------- 1 | 4 2 2 | 1 2 0 3 | 3 4 1 4 | 1 4 5 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree/distinct_characters_queries/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 5 2 | 2 3 | 5 4 | 2 5 | 6 6 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree/point_set_range_composite/tests/sample1.my: -------------------------------------------------------------------------------- 1 | 14005 2 | 470 3 | 8275 4 | 5500 5 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree/point_set_range_composite/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 14005 2 | 470 3 | 8275 4 | 5500 5 | -------------------------------------------------------------------------------- /test/data_structures/sqrt_decomposition_point_query/duff_is_mad/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 12 2 | 6 3 | 3 4 | 7 5 | 1 6 | -------------------------------------------------------------------------------- /test/data_structures/union_find_bipartite/prefix_enlightenment/tests/sample3.out: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | 1 4 | 1 5 | 1 6 | -------------------------------------------------------------------------------- /test/graphs/heavy_path_decomposition/vertex_add_path_sum/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 1111 2 | 10110 3 | 101110 4 | 1100 5 | -------------------------------------------------------------------------------- /test/misc/count_distinct_in_range/range_set_query/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 4 3 2 | 1 2 1 3 3 | 1 3 4 | 2 4 5 | 3 3 6 | -------------------------------------------------------------------------------- /test/numeric/discrete_logarithm/discrete_logarithm/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 0 2 | -1 3 | 4 4 | -1 5 | 4 6 | 0 7 | -1 8 | -------------------------------------------------------------------------------- /test/strings/knuth_morris_pratt/pattern_find/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 3 2 | ababab ab 3 | aaaaa bbb 4 | aafafaasf aaf 5 | -------------------------------------------------------------------------------- /test/strings/palindromes/enumerate_palindromes/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 1 0 1 0 1 4 1 0 7 0 1 4 1 0 1 0 1 4 1 0 1 2 | -------------------------------------------------------------------------------- /test/strings/polynomial_hash/good_substrings/tests/sample1.in: -------------------------------------------------------------------------------- 1 | ababab 2 | 01000000000000000000000000 3 | 1 4 | -------------------------------------------------------------------------------- /test/strings/polynomial_hash/good_substrings/tests/sample2.in: -------------------------------------------------------------------------------- 1 | acbacbacaa 2 | 00000000000000000000000000 3 | 2 4 | -------------------------------------------------------------------------------- /test/strings/trie/minimum_length_substring_with_k_occurrences/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 3 2 | 4 3 | 4 4 | -1 5 | 5 6 | -------------------------------------------------------------------------------- /test/data_structures/line_container/escape_through_leaf/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 3 2 | 2 10 -1 3 | 7 -7 5 4 | 2 3 5 | 2 1 6 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree_searchable/deda/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 3 4 2 | M 10 3 3 | M 5 1 4 | D 20 2 5 | D 5 1 6 | -------------------------------------------------------------------------------- /test/data_structures/static_to_dynamic_transformation/string_set_queries/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 3 2 | 2 3 | 1 4 | 0 5 | -------------------------------------------------------------------------------- /test/numeric/bignum_addpow2_compare/the_classic_problem/tests/sample2.in: -------------------------------------------------------------------------------- 1 | 4 3 2 | 1 2 4 3 | 2 3 5 4 | 3 4 6 5 | 1 4 6 | -------------------------------------------------------------------------------- /test/strings/knuth_morris_pratt/pattern_find/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 3 2 | 1 3 5 3 | 4 | Not Found 5 | 6 | 1 7 | 1 8 | -------------------------------------------------------------------------------- /test/data_structures/union_find_bipartite/prefix_enlightenment/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 3 5 | 3 6 | 3 7 | 3 8 | -------------------------------------------------------------------------------- /test/data_structures/line_container_monotonic/the_fair_nut_and_rectangles/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 3 2 | 4 4 8 3 | 1 5 0 4 | 5 2 10 5 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree_persistent/k-query/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 5 2 | 5 1 2 3 4 3 | 3 4 | 2 4 1 5 | 4 4 4 6 | 1 5 2 7 | -------------------------------------------------------------------------------- /test/data_structures/union_find/roads_not_only_in_berland/tests/sample2.in: -------------------------------------------------------------------------------- 1 | 7 2 | 1 2 3 | 2 3 4 | 3 1 5 | 4 5 6 | 5 6 7 | 6 7 8 | -------------------------------------------------------------------------------- /test/data_structures/union_find_bipartite/prefix_enlightenment/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | 1 4 | 1 5 | 1 6 | 1 7 | 4 8 | 4 9 | -------------------------------------------------------------------------------- /test/graphs/two_sat/two_sat/tests/sample1.in: -------------------------------------------------------------------------------- 1 | p cnf 5 6 2 | 1 2 0 3 | -3 -1 0 4 | -4 -3 0 5 | 2 -5 0 6 | 5 -2 0 7 | 1 4 0 8 | -------------------------------------------------------------------------------- /test/numeric/bignum_addpow2_compare/the_classic_problem/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 4 4 2 | 1 4 2 3 | 1 2 0 4 | 2 3 0 5 | 3 4 0 6 | 1 4 7 | -------------------------------------------------------------------------------- /test/strings/trie/minimum_length_substring_with_k_occurrences/tests/sample2.out: -------------------------------------------------------------------------------- 1 | -1 2 | 2 3 | -1 4 | 3 5 | -1 6 | 1 7 | -1 8 | -------------------------------------------------------------------------------- /test/graphs/tree/weighted_tree_diameter/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 8 2 | 0 1 5 3 | 1 2 3 4 | 2 3 1 5 | 1 4 2 6 | 4 7 4 7 | 1 5 7 8 | 2 6 5 9 | -------------------------------------------------------------------------------- /test/strings/mutable_string/count_matches_in_mutable_text/tests/sample1.in: -------------------------------------------------------------------------------- 1 | ababababa 2 | 3 3 | 2 1 7 aba 4 | 1 5 c 5 | 2 1 7 aba 6 | -------------------------------------------------------------------------------- /test/data_structures/line_container/escape_through_leaf/tests/sample2.in: -------------------------------------------------------------------------------- 1 | 4 2 | 5 -10 5 7 3 | -8 -80 -3 -10 4 | 2 1 5 | 2 4 6 | 1 3 7 | -------------------------------------------------------------------------------- /test/data_structures/line_container_monotonic/the_fair_nut_and_rectangles/tests/sample2.in: -------------------------------------------------------------------------------- 1 | 4 2 | 6 2 4 3 | 1 6 2 4 | 2 4 3 5 | 5 3 8 6 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree_lazy/range_add_range_min/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 4 2 | 1 2 3 4 3 | 4 4 | 3 0 5 | 3 0 -1 6 | 0 1 7 | 2 1 8 | -------------------------------------------------------------------------------- /test/data_structures/sparse_table/static_rmq/tests/sample1.out: -------------------------------------------------------------------------------- 1 | 2 2 | 2 3 | 1 4 | 1 5 | 10 6 | 1 7 | 1 8 | 1 9 | 1 10 | 100 11 | -------------------------------------------------------------------------------- /test/graphs/dijkstra/shortest_path/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 5 7 2 3 2 | 0 3 5 3 | 0 4 3 4 | 2 4 2 5 | 4 3 10 6 | 4 0 7 7 | 2 1 5 8 | 1 0 1 9 | -------------------------------------------------------------------------------- /test/graphs/lowest_common_ancestor/lowest_common_ancestor/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 5 5 2 | 0 0 2 2 3 | 0 1 4 | 0 4 5 | 1 2 6 | 2 3 7 | 3 4 8 | -------------------------------------------------------------------------------- /test/misc/count_distinct_in_range/army_creation/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 6 2 2 | 1 1 1 2 2 2 3 | 5 4 | 1 6 5 | 4 3 6 | 1 1 7 | 2 6 8 | 2 6 9 | -------------------------------------------------------------------------------- /test/misc/count_distinct_in_range/range_set_query/tests/sample2.out: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 2 4 | 1 5 | 2 6 | 2 7 | 6 8 | 3 9 | 3 10 | 3 11 | -------------------------------------------------------------------------------- /test/data_structures/line_container_monotonic/the_fair_nut_and_rectangles/tests/sample3.in: -------------------------------------------------------------------------------- 1 | 1 2 | 1000000000 1000000000 1000000000000000000 3 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree/point_add_range_sum/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 5 5 2 | 1 2 3 4 5 3 | 1 0 5 4 | 1 2 4 5 | 0 3 10 6 | 1 0 5 7 | 1 0 3 8 | -------------------------------------------------------------------------------- /test/data_structures/union_find_bipartite/prefix_enlightenment/tests/sample3.in: -------------------------------------------------------------------------------- 1 | 5 3 2 | 00011 3 | 3 4 | 1 2 3 5 | 1 6 | 4 7 | 3 8 | 3 4 5 9 | -------------------------------------------------------------------------------- /test/strings/mutable_string_bitset/count_matches_in_mutable_text/tests/sample1.in: -------------------------------------------------------------------------------- 1 | ababababa 2 | 3 3 | 2 1 7 aba 4 | 1 5 c 5 | 2 1 7 aba 6 | -------------------------------------------------------------------------------- /test/data_structures/line_container_monotonic/cats_transport/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 4 6 2 2 | 1 3 5 3 | 1 0 4 | 2 1 5 | 4 9 6 | 1 10 7 | 2 10 8 | 3 12 9 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree/distinct_characters_queries/tests/sample1.in: -------------------------------------------------------------------------------- 1 | abacaba 2 | 5 3 | 2 1 4 4 | 1 4 b 5 | 1 5 b 6 | 2 4 6 7 | 2 1 7 8 | -------------------------------------------------------------------------------- /test/data_structures/union_find_bipartite/prefix_enlightenment/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 7 3 2 | 0011100 3 | 3 4 | 1 4 6 5 | 3 6 | 3 4 7 7 | 2 8 | 2 3 9 | -------------------------------------------------------------------------------- /test/numeric/discrete_logarithm/discrete_logarithm/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 7 2 | 2 1 5 3 | 4 7 10 4 | 8 6 10 5 | 5 2 11 6 | 5 9 11 7 | 0 0 1 8 | 0 2 4 9 | -------------------------------------------------------------------------------- /test/strings/trie/minimum_length_substring_with_k_occurrences/tests/sample1.in: -------------------------------------------------------------------------------- 1 | aaaaa 2 | 5 3 | 3 a 4 | 3 aa 5 | 2 aaa 6 | 3 aaaa 7 | 1 aaaaa 8 | -------------------------------------------------------------------------------- /test/data_structures/binary_indexed_tree/point_add_range_sum/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 5 5 2 | 1 2 3 4 5 3 | 1 0 5 4 | 1 2 4 5 | 0 3 10 6 | 1 0 5 7 | 1 0 3 8 | -------------------------------------------------------------------------------- /test/data_structures/static_to_dynamic_transformation/string_set_queries/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 5 2 | 1 abc 3 | 3 abcabc 4 | 2 abc 5 | 1 aba 6 | 3 abababc 7 | -------------------------------------------------------------------------------- /test/strings/mutable_string/count_matches_in_mutable_text/tests/sample2.in: -------------------------------------------------------------------------------- 1 | abcdcbc 2 | 5 3 | 2 1 7 bc 4 | 1 4 b 5 | 2 4 7 bc 6 | 1 2 a 7 | 2 1 4 aa 8 | -------------------------------------------------------------------------------- /test/strings/mutable_string_bitset/count_matches_in_mutable_text/tests/sample2.in: -------------------------------------------------------------------------------- 1 | abcdcbc 2 | 5 3 | 2 1 7 bc 4 | 1 4 b 5 | 2 4 7 bc 6 | 1 2 a 7 | 2 1 4 aa 8 | -------------------------------------------------------------------------------- /test/strings/trie/minimum_length_substring_with_k_occurrences/tests/sample2.in: -------------------------------------------------------------------------------- 1 | abbb 2 | 7 3 | 4 b 4 | 1 ab 5 | 3 bb 6 | 1 abb 7 | 2 bbb 8 | 1 a 9 | 2 abbb 10 | -------------------------------------------------------------------------------- /test/data_structures/sparse_table/static_rmq/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 4 10 2 | 2 10 1 100 3 | 0 1 4 | 0 2 5 | 0 3 6 | 0 4 7 | 1 2 8 | 1 3 9 | 1 4 10 | 2 3 11 | 2 4 12 | 3 4 13 | -------------------------------------------------------------------------------- /test/data_structures/sqrt_decomposition_point_query/duff_is_mad/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 5 5 2 | a 3 | ab 4 | abab 5 | ababab 6 | b 7 | 1 5 4 8 | 3 5 4 9 | 1 5 2 10 | 1 5 3 11 | 1 4 1 12 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree_searchable/deda/tests/sample2.in: -------------------------------------------------------------------------------- 1 | 10 10 2 | M 20 10 3 | D 1 9 4 | M 2 3 5 | D 17 10 6 | M 20 2 7 | D 8 2 8 | M 40 1 9 | D 25 2 10 | M 33 9 11 | D 37 9 12 | -------------------------------------------------------------------------------- /test/data_structures/union_find_rewindable/connect_and_disconnect/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 5 11 2 | ? 3 | + 1 2 4 | + 2 3 5 | + 3 4 6 | + 4 5 7 | + 5 1 8 | ? 9 | - 2 3 10 | ? 11 | - 4 5 12 | ? 13 | -------------------------------------------------------------------------------- /test/misc/count_distinct_in_range/range_set_query/tests/sample2.in: -------------------------------------------------------------------------------- 1 | 10 10 2 | 2 5 6 5 2 1 7 9 7 2 3 | 5 5 4 | 2 4 5 | 6 7 6 | 2 2 7 | 7 8 8 | 7 9 9 | 1 8 10 | 6 9 11 | 8 10 12 | 6 8 13 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree/point_set_range_composite/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 5 5 2 | 1 2 3 | 3 4 4 | 5 6 5 | 7 8 6 | 9 10 7 | 1 0 5 11 8 | 1 2 4 12 9 | 0 1 13 14 10 | 1 0 4 15 11 | 1 2 5 16 12 | -------------------------------------------------------------------------------- /test/data_structures/union_find_bipartite/prefix_enlightenment/tests/sample2.in: -------------------------------------------------------------------------------- 1 | 8 6 2 | 00110011 3 | 3 4 | 1 3 8 5 | 5 6 | 1 2 5 6 7 7 | 2 8 | 6 8 9 | 2 10 | 3 5 11 | 2 12 | 4 7 13 | 1 14 | 2 15 | -------------------------------------------------------------------------------- /test/data_structures/union_find_bipartite/prefix_enlightenment/tests/sample4.in: -------------------------------------------------------------------------------- 1 | 19 5 2 | 1001001001100000110 3 | 2 4 | 2 3 5 | 2 6 | 5 6 7 | 2 8 | 8 9 9 | 5 10 | 12 13 14 15 16 11 | 1 12 | 19 13 | -------------------------------------------------------------------------------- /test/graphs/heavy_path_decomposition/vertex_add_path_sum/tests/sample1.in: -------------------------------------------------------------------------------- 1 | 5 5 2 | 1 10 100 1000 10000 3 | 0 1 4 | 1 2 5 | 2 3 6 | 1 4 7 | 1 0 3 8 | 1 2 4 9 | 0 1 100000 10 | 1 1 3 11 | 1 3 2 12 | -------------------------------------------------------------------------------- /test/data_structures/static_to_dynamic_transformation/string_set_queries/tests/sample2.in: -------------------------------------------------------------------------------- 1 | 10 2 | 1 abc 3 | 1 bcd 4 | 1 abcd 5 | 3 abcd 6 | 2 abcd 7 | 3 abcd 8 | 2 bcd 9 | 3 abcd 10 | 2 abc 11 | 3 abcd 12 | -------------------------------------------------------------------------------- /test/data_structures/union_find_bipartite/prefix_enlightenment/tests/sample4.out: -------------------------------------------------------------------------------- 1 | 0 2 | 1 3 | 1 4 | 1 5 | 2 6 | 2 7 | 2 8 | 3 9 | 3 10 | 3 11 | 3 12 | 4 13 | 4 14 | 4 15 | 4 16 | 4 17 | 4 18 | 4 19 | 5 20 | -------------------------------------------------------------------------------- /test/graphs/dijkstra/train/tests/sample4.in: -------------------------------------------------------------------------------- 1 | 9 14 6 7 2 | 3 1 4 1 3 | 5 9 2 6 4 | 5 3 5 8 5 | 9 7 9 3 6 | 2 3 8 4 7 | 6 2 6 4 8 | 3 8 3 2 9 | 7 9 5 2 10 | 8 4 1 9 11 | 7 1 6 9 12 | 3 9 9 3 13 | 7 5 1 5 14 | 8 2 9 7 15 | 4 9 4 4 16 | 17 | -------------------------------------------------------------------------------- /.circleci/util.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | def canonical_path(fpath, extension = ".cpp"): 4 | if fpath[-len(extension):] != extension: 5 | fpath += extension 6 | if fpath[0] == '~': 7 | fpath = os.path.expanduser(fpath) 8 | return os.path.abspath(fpath) 9 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree/distinct_characters_queries/tests/sample2.in: -------------------------------------------------------------------------------- 1 | dfcbbcfeeedbaea 2 | 15 3 | 1 6 e 4 | 1 4 b 5 | 2 6 14 6 | 1 7 b 7 | 1 12 c 8 | 2 6 8 9 | 2 1 6 10 | 1 7 c 11 | 1 2 f 12 | 1 10 a 13 | 2 7 9 14 | 1 10 a 15 | 1 14 b 16 | 1 1 f 17 | 2 1 11 18 | -------------------------------------------------------------------------------- /test/numeric/tonelli-shanks/sqrt_mod/sqrt_mod.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://judge.yosupo.jp/problem/sqrt_mod 2 | 3 | #include 4 | 5 | // {{{ numeric/tonelli-shanks.cpp }}} 6 | 7 | int main() { 8 | int T; 9 | scanf("%d", &T); 10 | 11 | for (int t = 0; t < T; t++) { 12 | int Y, P; 13 | scanf("%d %d", &Y, &P); 14 | 15 | printf("%d\n", sqrt(Y, P)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/strings/z_algorithm/z_algorithm/z_algorithm.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://judge.yosupo.jp/problem/zalgorithm 2 | 3 | // {{{ strings/z_algorithm.cpp }}} 4 | 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | int main() { 10 | string S; 11 | cin >> S; 12 | 13 | auto z = z_algorithm(S.begin(), S.end()); 14 | 15 | for (int i = 0; i < int(z.size()); i++) { 16 | if (i) cout << " "; 17 | cout << z[i]; 18 | } 19 | cout << endl; 20 | } 21 | -------------------------------------------------------------------------------- /test/numeric/discrete_logarithm/discrete_logarithm/discrete_logarithm.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://judge.yosupo.jp/problem/discrete_logarithm_mod 2 | 3 | #include 4 | 5 | // {{{ numeric/discrete_logarithm.cpp }}} 6 | 7 | int main() { 8 | int T; 9 | scanf("%d", &T); 10 | 11 | for (int t = 0; t < T; t++) { 12 | int x, y, m; 13 | scanf("%d %d %d", &x, &y, &m); 14 | 15 | int ans = discrete_log(x, y, m); 16 | 17 | printf("%d\n", ans); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/strings/suffix_array/suffix_array/suffix_array.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://judge.yosupo.jp/problem/suffixarray 2 | 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // {{{ strings/suffix_array.cpp }}} 8 | 9 | int main() { 10 | string S; 11 | cin >> S; 12 | 13 | suffix_array sa(S.begin(), S.end()); 14 | 15 | for (int i = 0; i < int(S.size()); i++) { 16 | if (i) cout << " "; 17 | cout << sa.suffix_at_rank(i); 18 | } 19 | cout << endl; 20 | } 21 | -------------------------------------------------------------------------------- /test/numeric/modnum/exponentiation/exponentiation.cpp: -------------------------------------------------------------------------------- 1 | // https://cses.fi/problemset/task/1712 2 | 3 | // {{{ numeric/modnum.cpp }}} 4 | 5 | using mn = modnum; 6 | using mn_exp = modnum; 7 | 8 | int main() { 9 | int N; 10 | scanf("%d", &N); 11 | 12 | for (int i = 0; i < N; i++) { 13 | int a, b, c; 14 | scanf("%d %d %d", &a, &b, &c); 15 | 16 | mn_exp e = mn_exp(b).pow(c); 17 | mn ans = mn(a).pow(int(e)); 18 | 19 | printf("%d\n", int(ans)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /graphs/maximum_matching.cpp: -------------------------------------------------------------------------------- 1 | int maximum_matching(const int N, const vector>& edges) { 2 | const int INF = 1e9 + 7; 3 | uniform_int_distribution unif(1, INF - 1); 4 | 5 | int res = 0; 6 | for (int rep = 0; rep < 3; rep++) { 7 | matrix> m(N, 0, 0); 8 | for (auto [u, v] : edges) { 9 | if (u > v) swap(u, v); 10 | int eid = unif(rng); 11 | m(u, v) = eid; 12 | m(v, u) = -eid; 13 | } 14 | res = max(res, m.rank()); 15 | } 16 | return res / 2; 17 | } 18 | -------------------------------------------------------------------------------- /test/data_structures/sparse_table/static_rmq/static_rmq.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // {{{ data_structures/sparse_table.cpp }}} 4 | 5 | int main() { 6 | int N, Q; 7 | scanf("%d %d", &N, &Q); 8 | 9 | std::vector a(N); 10 | for (int i = 0; i < N; i++) 11 | scanf("%d", &a[i]); 12 | 13 | sparse_table st(N, std::min, [&](int i) { return a[i]; }); 14 | 15 | for (int q = 0; q < Q; q++) { 16 | int l, r; 17 | scanf("%d %d", &l, &r); 18 | 19 | printf("%d\n", st.accumulate(l, r)); 20 | } 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /test/strings/suffix_array/count_distinct_substrings/count_distinct_substrings.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://judge.yosupo.jp/problem/number_of_substrings 2 | 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // {{{ strings/suffix_array.cpp }}} 8 | 9 | int main() { 10 | string s; 11 | cin >> s; 12 | 13 | suffix_array sa(s.begin(), s.end()); 14 | 15 | int64_t ans = int64_t(s.size()) * (s.size() + 1) / 2 16 | - accumulate(sa.lcp_between_ranks.begin(), sa.lcp_between_ranks.end(), int64_t(0)); 17 | 18 | printf("%jd\n", ans); 19 | } 20 | -------------------------------------------------------------------------------- /test/strings/palindromes/enumerate_palindromes/enumerate_palindromes.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://judge.yosupo.jp/problem/enumerate_palindromes 2 | 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // {{{ strings/palindromes.cpp }}} 8 | 9 | int main() { 10 | string S; 11 | cin >> S; 12 | 13 | palindromes p(S.begin(), S.end()); 14 | 15 | for (int i = 0; i < int(S.size()); i++) { 16 | if (i) cout << " "; 17 | cout << p.longest_centered_at(i); 18 | 19 | if (i+1 < int(S.size())) 20 | cout << " " << p.longest_centered_right_of(i); 21 | } 22 | cout << endl; 23 | } 24 | -------------------------------------------------------------------------------- /test/graphs/lowest_common_ancestor/lowest_common_ancestor/lowest_common_ancestor.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://judge.yosupo.jp/problem/lca 2 | 3 | #include 4 | using namespace std; 5 | 6 | // {{{ graphs/lowest_common_ancestor.cpp }}} 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(nullptr); 11 | 12 | int N, Q; 13 | cin >> N >> Q; 14 | 15 | tree t(N, 0); 16 | re(t, PARENT_LIST, 0); 17 | 18 | lowest_common_ancestor lca(t); 19 | 20 | for (int q = 0; q < Q; q++) { 21 | int u, v; 22 | cin >> u >> v; 23 | 24 | cout << lca.lca(u, v) << "\n"; 25 | } 26 | 27 | return 0; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /strings/z_algorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* Returns z[i] = the greatest length L such that 4 | * s[i, i+L) is identical to s[0, L). 5 | */ 6 | template 7 | std::vector z_algorithm(RandomAccessIterator first, RandomAccessIterator last) { 8 | int N = int(last - first); 9 | 10 | std::vector z(N); 11 | z[0] = N; 12 | 13 | for (int i = 1, l, r = -1; i < N; i++) { 14 | z[i] = r > i ? std::min(r - i, z[i - l]) : 0; 15 | while (i + z[i] < N && first[i + z[i]] == first[z[i]]) 16 | z[i]++; 17 | if (i + z[i] > r) 18 | l = i, r = i + z[i]; 19 | } 20 | 21 | return z; 22 | }; 23 | -------------------------------------------------------------------------------- /test/misc/count_distinct_in_range/range_set_query/range_set_query.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://atcoder.jp/contests/abc174/tasks/abc174_f 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | // {{{ misc/count_distinct_in_range.cpp }}} 8 | 9 | int main() { 10 | int N, Q; 11 | scanf("%d %d", &N, &Q); 12 | 13 | std::vector colors(N); 14 | for (int i = 0; i < N; i++) 15 | scanf("%d", &colors[i]); 16 | 17 | count_distinct_in_range cd(colors.begin(), colors.end()); 18 | 19 | for (int q = 0; q < Q; q++) { 20 | int l, r; 21 | scanf("%d %d", &l, &r); 22 | printf("%d\n", cd.get_count(l - 1, r)); 23 | } 24 | 25 | return 0; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /test/numeric/ntt/convolution_mod_998244353/convolution_mod_998244353.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://judge.yosupo.jp/problem/convolution_mod 2 | 3 | #include 4 | using namespace std; 5 | 6 | // {{{ numeric/ntt.cpp }}} 7 | using namespace ntt; 8 | 9 | using mn = modnum<998244353>; 10 | 11 | int main() { 12 | int N, M; 13 | scanf("%d %d", &N, &M); 14 | 15 | vector a(N); 16 | for (int i = 0; i < N; i++) 17 | scanf("%d", &a[i].v); 18 | 19 | vector b(M); 20 | for (int i = 0; i < M; i++) 21 | scanf("%d", &b[i].v); 22 | 23 | vector c = a * b; 24 | for (int i = 0; i < int(c.size()); i++) { 25 | if (i) printf(" "); 26 | printf("%d", int(c[i])); 27 | } 28 | printf("\n"); 29 | } 30 | -------------------------------------------------------------------------------- /test/numeric/complex_fft/convolution_mod_1000000007/convolution_mod_1000000007.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://judge.yosupo.jp/problem/convolution_mod_1000000007 2 | 3 | #include 4 | using namespace std; 5 | 6 | // {{{ numeric/complex_fft.cpp }}} 7 | using namespace complex_fft; 8 | 9 | using mn = modnum; 10 | 11 | int main() { 12 | int N, M; 13 | scanf("%d %d", &N, &M); 14 | 15 | vector a(N); 16 | for (int i = 0; i < N; i++) 17 | scanf("%d", &a[i].v); 18 | 19 | vector b(M); 20 | for (int i = 0; i < M; i++) 21 | scanf("%d", &b[i].v); 22 | 23 | vector c = a * b; 24 | for (int i = 0; i < int(c.size()); i++) { 25 | if (i) printf(" "); 26 | printf("%d", int(c[i])); 27 | } 28 | printf("\n"); 29 | } 30 | -------------------------------------------------------------------------------- /test/strings/suffix_automaton/count_distinct_substrings/count_distinct_substrings.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://judge.yosupo.jp/problem/number_of_substrings 2 | 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // {{{ strings/suffix_automaton.cpp }}} 8 | 9 | int main() { 10 | string s; 11 | cin >> s; 12 | 13 | suffix_automaton<'a', 26> sa(s.begin(), s.end()); 14 | 15 | vector reachable_endpos(int(sa.data.size())); 16 | 17 | for (int loc : sa.reverse_length_order) { 18 | reachable_endpos[loc] = sa.ct_end_pos[loc] > 0; 19 | for (int nbr : sa.data[loc].transitions) 20 | if (nbr != -1) 21 | reachable_endpos[loc] += reachable_endpos[nbr]; 22 | } 23 | 24 | printf("%jd\n", reachable_endpos[0]); 25 | } 26 | -------------------------------------------------------------------------------- /graphs/topological_sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // If there is a cycle, the returned array will not contain all vertices. 4 | std::vector topological_sort(const std::vector> &adj) { 5 | const int n = int(adj.size()); 6 | std::vector deg(n); 7 | std::vector ans; 8 | 9 | for (int i = 0; i < n; i++) { 10 | for (int j : adj[i]) 11 | deg[j]++; 12 | } 13 | 14 | for (int i = 0; i < n; i++) { 15 | if (deg[i] == 0) 16 | ans.push_back(i); 17 | } 18 | 19 | int q = 0; 20 | while (q < int(ans.size())) { 21 | int cur = ans[q++]; 22 | for (int next : adj[cur]) { 23 | if (--deg[next] == 0) 24 | ans.push_back(next); 25 | } 26 | } 27 | 28 | return ans; 29 | } 30 | -------------------------------------------------------------------------------- /data_structures/line.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template::value> 5 | struct line { 6 | static constexpr T infinity = std::numeric_limits::has_infinity ? 7 | std::numeric_limits::infinity() : std::numeric_limits::max(); 8 | 9 | T a, b; 10 | mutable T intersects_next = infinity; 11 | 12 | T evaluate(T x) const { 13 | return a * x + b; 14 | } 15 | 16 | static T div(const T &a, const T &b) { 17 | if constexpr (T_integral) 18 | return a / b - ((a ^ b) < 0 && (a % b)); 19 | else 20 | return a / b; 21 | } 22 | 23 | T compute_intersection(const line &o) const { 24 | if (a == o.a) return b > o.b ? infinity : -infinity; 25 | return div(o.b - b, a - o.a); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /test/misc/count_distinct_in_range/army_creation/army_creation.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://codeforces.com/contest/813/problem/E 2 | 3 | #include 4 | #include 5 | 6 | // {{{ misc/count_distinct_in_range }}} 7 | 8 | int main() { 9 | int N, K; 10 | scanf("%d %d", &N, &K); 11 | 12 | std::vector a(N); 13 | for (int i = 0; i < N; i++) 14 | scanf("%d", &a[i]); 15 | 16 | count_distinct_in_range cd(a.begin(), a.end(), K); 17 | 18 | int Q, last = 0; 19 | scanf("%d", &Q); 20 | 21 | for (int q = 0; q < Q; q++) { 22 | int x, y; 23 | scanf("%d %d", &x, &y); 24 | 25 | int l = (x + last) % N; 26 | int r = (y + last) % N; 27 | if (l > r) std::swap(l, r); 28 | 29 | printf("%d\n", last = cd.get_count(l, r + 1)); 30 | } 31 | 32 | return 0; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree/point_add_range_sum/point_add_range_sum.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://judge.yosupo.jp/problem/point_add_range_sum 2 | 3 | #include 4 | #include 5 | 6 | // {{{ data_structures/segment_tree.cpp }}} 7 | 8 | int main() { 9 | int N, Q; 10 | scanf("%d %d", &N, &Q); 11 | 12 | segment_tree> s(N, 0, std::plus()); 13 | 14 | s.assign([](int i) { int a; scanf("%d", &a); return a; }); 15 | 16 | for (int q = 0; q < Q; q++) { 17 | int t; 18 | scanf("%d", &t); 19 | if (t == 0) { 20 | int p, x; 21 | scanf("%d %d", &p, &x); 22 | s.assign(p, s[p] + x); 23 | } else { 24 | int l, r; 25 | scanf("%d %d", &l, &r); 26 | printf("%ld\n", s.accumulate(l, r)); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/graphs/dijkstra/shortest_path/shortest_path.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // {{{ graphs/dijkstra.cpp }}} 5 | 6 | int main() { 7 | int N, M, s, t; 8 | scanf("%d %d %d %d", &N, &M, &s, &t); 9 | 10 | WeightedDirectedGraph graph(N); 11 | for (int i = 0; i < M; i++) { 12 | int a, b, c; 13 | scanf("%d %d %d", &a, &b, &c); 14 | 15 | graph.add_directed_edge(a, b, c); 16 | } 17 | 18 | ShortestPathTree tree(graph, {s}, 0, std::plus(), std::less()); 19 | 20 | if (!tree.is_reachable(t)) { 21 | printf("-1\n"); 22 | return 0; 23 | } 24 | 25 | std::vector path = tree.list_vertices_on_path(t); 26 | 27 | printf("%jd %d\n", tree.distance(t), int(path.size()) - 1); 28 | 29 | for (int i = 0; i + 1 < int(path.size()); i++) 30 | printf("%d %d\n", path[i], path[i + 1]); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /data_structures/monotonic_stack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | template > 7 | struct monotonic_stack { 8 | std::stack> data; 9 | LessThan less_than; 10 | 11 | public: 12 | bool empty() const { return data.empty(); } 13 | int size() const { return data.size(); } 14 | T top() const { return data.top().first; }; 15 | 16 | void push(const T &item) { 17 | T next_min = empty() ? item : std::min(item, min(), less_than); 18 | data.push({item, next_min}); 19 | } 20 | 21 | void pop() { 22 | assert(!empty()); 23 | data.pop(); 24 | } 25 | 26 | T min() const { 27 | assert(!empty()); 28 | return data.top().second; 29 | }; 30 | 31 | T min(const T &default_value) const { return empty() ? default_value : min(); } 32 | }; 33 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree_searchable/deda/deda.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://oj.uz/problem/submit/COCI17_deda 2 | 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // {{{ data_structures/segment_tree_searchable }}} 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | int N, Q; 14 | cin >> N >> Q; 15 | 16 | auto smaller = [](int a, int b) { return min(a, b); }; 17 | searchable_segment_tree sst(N, INT_MAX, smaller); 18 | 19 | for (int q = 0; q < Q; q++) { 20 | char op; 21 | int x, y; 22 | cin >> op >> x >> y; 23 | 24 | if (op == 'M') { 25 | sst.assign(y - 1, x); 26 | } else { 27 | int ans = sst.binary_search(y - 1, [&x](int v) { return v <= x; }); 28 | cout << (ans > N ? -1 : ans) << "\n"; 29 | } 30 | } 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /test/strings/mutable_string/count_matches_in_mutable_text/count_matches_in_mutable_text.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://codeforces.com/contest/914/problem/F 2 | 3 | #include 4 | using namespace std; 5 | 6 | // {{{ strings/mutable_string.cpp }}} 7 | 8 | int main() { 9 | ios::sync_with_stdio(false); 10 | cin.tie(nullptr); 11 | 12 | string init; 13 | cin >> init; 14 | 15 | mutable_string<'a', 26> s(init.begin(), init.end()); 16 | 17 | int Q; 18 | cin >> Q; 19 | 20 | for (int q = 0; q < Q; q++) { 21 | int t; 22 | cin >> t; 23 | 24 | if (t == 1) { 25 | int i; 26 | char c; 27 | cin >> i >> c; 28 | 29 | s.assign(i - 1, c); 30 | } else { 31 | int l, r; 32 | string y; 33 | cin >> l >> r >> y; 34 | 35 | cout << s.count_matches_in_substring(y.begin(), y.end(), l - 1, r) << "\n"; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/strings/mutable_string_bitset/count_matches_in_mutable_text/count_matches_in_mutable_text.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://codeforces.com/contest/914/problem/F 2 | 3 | #include 4 | using namespace std; 5 | 6 | // {{{ strings/mutable_string_bitset.cpp }}} 7 | 8 | int main() { 9 | ios::sync_with_stdio(false); 10 | cin.tie(nullptr); 11 | 12 | string init; 13 | cin >> init; 14 | 15 | mutable_string_bitset<'a', 26, 100000> s(init.begin(), init.end()); 16 | 17 | int Q; 18 | cin >> Q; 19 | 20 | for (int q = 0; q < Q; q++) { 21 | int t; 22 | cin >> t; 23 | 24 | if (t == 1) { 25 | int i; 26 | char c; 27 | cin >> i >> c; 28 | 29 | s.assign(i - 1, c); 30 | } else { 31 | int l, r; 32 | string y; 33 | cin >> l >> r >> y; 34 | 35 | cout << s.count_matches(y.begin(), y.end(), l - 1, r) << "\n"; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/data_structures/binary_indexed_tree/point_add_range_sum/point_add_range_sum.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://judge.yosupo.jp/problem/point_add_range_sum 2 | 3 | #include 4 | #include 5 | 6 | // {{{ data_structures/binary_indexed_tree.cpp }}} 7 | 8 | int main() { 9 | int N, Q; 10 | scanf("%d %d", &N, &Q); 11 | 12 | binary_indexed_tree, std::minus> bit(N, 0, std::plus(), std::minus()); 13 | 14 | for (int i = 0; i < N; i++) { 15 | int a; 16 | scanf("%d", &a); 17 | bit.add(i, a); 18 | } 19 | 20 | for (int q = 0; q < Q; q++) { 21 | int t; 22 | scanf("%d", &t); 23 | if (t == 0) { 24 | int p, x; 25 | scanf("%d %d", &p, &x); 26 | bit.add(p, x); 27 | } else { 28 | int l, r; 29 | scanf("%d %d", &l, &r); 30 | printf("%ld\n", bit.accumulate(l, r)); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /.circleci/run_tests.py: -------------------------------------------------------------------------------- 1 | import re 2 | import os 3 | import sys 4 | 5 | from util import canonical_path 6 | from expand_dependencies import expand 7 | from test_harness import build_and_run 8 | 9 | def run_tests(infile, clib_root): 10 | if os.path.isdir(infile): 11 | infile = os.path.normpath(infile) 12 | test_name = os.path.basename(infile) 13 | 14 | infile += "/" + test_name + ".cpp" 15 | 16 | infile = canonical_path(infile) 17 | 18 | dirname = os.path.dirname(infile) 19 | basename = os.path.basename(infile) 20 | expanded_file = dirname + "/." + basename 21 | 22 | expand(infile, expanded_file, clib_root) 23 | 24 | build_and_run(expanded_file) 25 | 26 | if __name__ == "__main__": 27 | if len(sys.argv) < 2: 28 | print("Path to source file expected as argument") 29 | exit(1) 30 | 31 | clib_root = "~/clib/" 32 | if len(sys.argv) >= 3: 33 | clib_root = sys.argv[2] 34 | 35 | run_tests(sys.argv[1], clib_root) 36 | -------------------------------------------------------------------------------- /test/strings/knuth_morris_pratt/pattern_find/pattern_find.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://www.spoj.com/problems/NAJPF/ 2 | 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // {{{ strings/knuth_morris_pratt.cpp }}} 8 | 9 | int main() { 10 | int T; 11 | cin >> T; 12 | 13 | for (int t = 0; t < T; t++) { 14 | if (t) cout << "\n"; 15 | 16 | string text, pattern; 17 | cin >> text >> pattern; 18 | 19 | knuth_morris_pratt kmp(pattern.begin(), pattern.end()); 20 | 21 | std::vector matches = kmp.indices_of_matches(text.begin(), text.end()); 22 | 23 | if (matches.empty()) { 24 | cout << "Not Found\n"; 25 | } else { 26 | cout << matches.size() << "\n"; 27 | for (int i = 0; i < int(matches.size()); i++) { 28 | if (i) cout << " "; 29 | cout << matches[i] + 1; 30 | } 31 | cout << "\n"; 32 | } 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /graphs/graph.cpp: -------------------------------------------------------------------------------- 1 | template struct graph { 2 | int V, EC; 3 | vvi nbrs; 4 | vector>> edges; 5 | vector edge_list; 6 | 7 | graph(int _V = 0, int _EC = 0) : V(_V), EC(_EC) {} 8 | graph(int _V, const vector& __edge_list) : V(_V), EC(sz(__edge_list)), edge_list(__edge_list) { 9 | nbrs.resize(V), edges.resize(V); 10 | for (E& e : edge_list) { 11 | assert(0 <= e.u && e.u < V && 0 <= e.v && e.v < V); 12 | nbrs[e.u].push_back(e.v); 13 | nbrs[e.v].push_back(e.u); 14 | edges[e.u].pb(e); 15 | edges[e.v].pb(e); 16 | } 17 | } 18 | 19 | friend void re(graph& g) { 20 | assert(g.V > 0); 21 | vector __edge_list(g.EC); 22 | re(__edge_list); 23 | for (int i = 0; i < g.EC; i++) __edge_list[i].i = i; 24 | g = graph(__edge_list); 25 | } 26 | friend void pr(const graph& g) { pr("{V=", g.V, " ", g.edge_list, "}"); } 27 | }; 28 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree/distinct_characters_queries/distinct_characters_queries.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://codeforces.com/problemset/problem/1234/D 2 | 3 | #include 4 | using namespace std; 5 | 6 | // {{{ data_structures/segment_tree }}} 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(nullptr); 11 | 12 | string s; 13 | cin >> s; 14 | 15 | segment_tree> st(int(s.size()), 0, bit_or()); 16 | 17 | st.assign([&s](int i) { return 1 << (s[i] - 'a'); }); 18 | 19 | int Q; 20 | cin >> Q; 21 | for (int q = 0; q < Q; q++) { 22 | int t; 23 | cin >> t; 24 | if (t == 1) { 25 | int pos; 26 | char c; 27 | cin >> pos >> c; 28 | 29 | st.assign(pos - 1, 1 << (c - 'a')); 30 | } else { 31 | int l, r; 32 | cin >> l >> r; 33 | 34 | cout << __builtin_popcount(st.accumulate(l - 1, r)) << "\n"; 35 | } 36 | } 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /misc/subset_sum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | /* Accepts a collection of integers with sum at most MAX_SUM. 6 | * Computes its set of subset sums in O(MAX_SUM * sqrt(sum) / MACHINE_WORD_SIZE) 7 | */ 8 | template 9 | std::bitset subset_sum(InputIterator first, InputIterator last) { 10 | int sum = accumulate(first, last, 0); 11 | assert(sum <= MAX_SUM); 12 | 13 | static std::vector count(MAX_SUM + 1); 14 | 15 | for (InputIterator iter = first; iter != last; iter++) 16 | count[*iter]++; 17 | 18 | std::bitset result; 19 | result[0] = 1; 20 | 21 | for (int val = 1; val <= sum; val++) { 22 | if (count[val] > 2) { 23 | int pairs = (count[val] - 1) / 2; 24 | count[2 * val] += pairs; 25 | count[val] -= 2 * pairs; 26 | } 27 | 28 | while (count[val]) { 29 | result |= result << val; 30 | count[val]--; 31 | } 32 | } 33 | 34 | return result; 35 | } 36 | -------------------------------------------------------------------------------- /test/graphs/two_sat/two_sat/two_sat.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://judge.yosupo.jp/problem/two_sat 2 | 3 | #include 4 | 5 | // {{{ graphs/two_sat.cpp }}} 6 | 7 | int main() { 8 | char c; 9 | for (int i = 0; i < 4; i++) 10 | scanf(" %c", &c); 11 | 12 | int N, M; 13 | scanf("%d %d", &N, &M); 14 | 15 | two_sat ts(N); 16 | 17 | for (int i = 0; i < M; i++) { 18 | int a, b; 19 | scanf("%d %d %c", &a, &b, &c); 20 | 21 | int x = 2 * (abs(a) - 1) + int(a > 0); 22 | int y = 2 * (abs(b) - 1) + int(b > 0); 23 | 24 | ts.constraint_at_least_one(x, y); 25 | } 26 | 27 | std::vector assignment = ts.solve(); 28 | 29 | if (assignment.empty()) { 30 | printf("s UNSATISFIABLE\n"); 31 | } else { 32 | printf("s SATISFIABLE\n"); 33 | printf("v"); 34 | 35 | for (int i = 0; i < N; i++) { 36 | printf(" "); 37 | if (!assignment[i]) 38 | printf("-"); 39 | printf("%d", i + 1); 40 | } 41 | 42 | printf(" 0\n"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /numeric/garner.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Garner's algorithm: finds the unique v modulo prod(MODS) 3 | * such that v is congruent to n[i] modulo MODS[i] for all i. 4 | * Elements of MODS should be pairwise co-prime. 5 | */ 6 | 7 | template V crt(const vector MODS, const vector n) { 8 | auto inverse = [](V M, V n) { 9 | V g = M, x = 0, y = 1; 10 | for (V r = n; r != 0; ) { 11 | V q = g / r; 12 | g %= r; swap(g, r); 13 | x -= q * y; swap(x, y); 14 | } 15 | 16 | assert(g == 1); 17 | assert(y == M || y == -M); 18 | return x < 0 ? x + M : x; 19 | }; 20 | 21 | const int M = sz(MODS); 22 | 23 | vector x(M); 24 | for (int i = 0; i < M; i++) { 25 | x[i] = n[i]; 26 | for (int j = 0; j < i; j++) { 27 | x[i] = V(x[i] - x[j]) * inverse(MODS[i], MODS[j] % MODS[i]) % MODS[i]; 28 | if (x[i] < 0) x[i] += MODS[i]; 29 | } 30 | } 31 | 32 | V v = 0; 33 | for (int i = M - 1; i >= 0; i--) 34 | v = MODS[i] * v + x[i]; 35 | return v; 36 | } 37 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree_persistent/k-query/k-query.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://www.spoj.com/problems/KQUERY/ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | // {{{ data_structures/segment_tree_persistent }}} 11 | 12 | int main() { 13 | int N; 14 | scanf("%d", &N); 15 | 16 | vector a(N); 17 | for (int i = 0; i < N; i++) 18 | scanf("%d", &a[i]); 19 | 20 | segment_tree_persistent> st(N, 0, plus()); 21 | 22 | vector insert_order(N); 23 | iota(insert_order.begin(), insert_order.end(), 0); 24 | sort(insert_order.begin(), insert_order.end(), [&](int i, int j) { return a[i] > a[j]; }); 25 | 26 | for (int i : insert_order) 27 | st.assign(i, 1, -a[i]); 28 | 29 | int Q; 30 | scanf("%d", &Q); 31 | 32 | for (int q = 0; q < Q; q++) { 33 | int i, j, k; 34 | scanf("%d %d %d", &i, &j, &k); 35 | 36 | printf("%d\n", st.accumulate(i - 1, j, -k)); 37 | } 38 | 39 | return 0; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /data_structures/static_to_dynamic_transformation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | struct static_to_dynamic_transformation { 6 | int SZ; 7 | std::vector elements; 8 | std::vector collections; 9 | 10 | static_to_dynamic_transformation() : SZ(0) {} 11 | 12 | void insert(T elt) { 13 | elements.push_back(elt); 14 | 15 | int index = __builtin_ctz(int(elements.size())); 16 | 17 | if (index >= int(collections.size())) 18 | collections.emplace_back(); 19 | 20 | collections[index] = { elements.end() - (1 << index), elements.end() }; 21 | 22 | std::fill(collections.begin(), collections.begin() + index, StaticCollection{}); 23 | } 24 | 25 | template 26 | Result accumulate(Query query, Result init, CommutativeJoinResults join) const { 27 | for (const StaticCollection &c : collections) 28 | init = join(init, query(c)); 29 | return init; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /numeric/berlekamp-massey.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template struct LFSR { 5 | std::vector seq; 6 | std::vector fib; 7 | std::vector galois; 8 | 9 | LFSR(std::vector seq_) : seq(seq_) { 10 | std::vector C = {1}, B = {1}; T b = 1; 11 | for (int i = 0, m = 1; i < int(seq.size()); i++, m++) { 12 | T d = 0; for (int j = 0; j < int(C.size()); j++) d += C[j] * seq[i - j]; 13 | if (d == 0) continue; 14 | std::vector B_ = C; C.resize(std::max(int(C.size()), m+int(B.size()))); 15 | T dbi = d/b; for (int j = 0; j < int(B.size()); j++) C[m+j] -= dbi * B[j]; 16 | if (int(B_.size()) < m+int(B.size())) { B = B_; b = d; m = 0; } 17 | } 18 | galois = vector_operators::reversed(C); 19 | fib = move(C); fib.erase(fib.begin()); fib *= T{-1}; 20 | } 21 | 22 | T operator[](int64_t n) const { 23 | std::vector r = vector_operators::dot(seq, vector_operators::mod_pow({0,1}, n, galois)); 24 | return accumulate((r).begin(), (r).end(), T{0}); 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /test/data_structures/union_find_rewindable/connect_and_disconnect/connect_and_disconnect.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://codeforces.com/gym/100551/problem/A 2 | 3 | #ifdef ONLINE_JUDGE 4 | #include 5 | std::ifstream cin("connect.in"); 6 | std::ofstream cout("connect.out"); 7 | #else 8 | #include 9 | #endif 10 | 11 | using namespace std; 12 | 13 | // {{{ data_structures/union_find_rewindable }}} 14 | 15 | int main() { 16 | int N, K; 17 | cin >> N >> K; 18 | 19 | vector> edge_sequence; 20 | 21 | vector queries; 22 | 23 | for (int i = 0; i < K; i++) { 24 | char op; 25 | cin >> op; 26 | if (op == '?') { 27 | queries.push_back(int(edge_sequence.size())); 28 | } else { 29 | int u, v; 30 | cin >> u >> v; 31 | if (u > v) std::swap(u, v); 32 | edge_sequence.emplace_back(u - 1, v - 1); 33 | } 34 | } 35 | 36 | vector component_counts = get_component_counts(N, edge_sequence); 37 | 38 | for (int q : queries) 39 | cout << component_counts[q] << "\n"; 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /misc/stable_counting_sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace stable_counting_sort { 6 | template 7 | T identity(const T& t) { return t; } 8 | 9 | template 10 | const std::vector& permutation(int SZ, int MAX_KEY, 11 | const T_extract_key &extract_key = identity) { 12 | 13 | static std::vector p; 14 | p.resize(SZ); 15 | 16 | if (SZ < 256) { 17 | std::iota(p.begin(), p.end(), 0); 18 | std::sort(p.begin(), p.end(), [&](int a, int b) { 19 | return extract_key(a) < extract_key(b); 20 | }); 21 | } else { 22 | static std::vector count; 23 | count.assign(MAX_KEY, 0); 24 | for (int i = 0; i < SZ; i++) 25 | count[extract_key(i)]++; 26 | for (int i = 0; i < MAX_KEY - 1; i++) 27 | count[i + 1] += count[i]; 28 | for (int i = SZ - 1; i >= 0; i--) 29 | p[--count[extract_key(i)]] = i; 30 | } 31 | 32 | return p; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /test/graphs/dijkstra/train/train.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://atcoder.jp/contests/abc192/tasks/abc192_e 2 | 3 | #include 4 | using namespace std; 5 | 6 | // {{{ graphs/dijkstra }}} 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(nullptr); 11 | 12 | int N, M, X, Y; 13 | cin >> N >> M >> X >> Y; 14 | --X, --Y; 15 | 16 | struct EdgeWeight { 17 | int t, k; 18 | }; 19 | 20 | WeightedDirectedGraph g(N); 21 | 22 | for (int i = 0; i < M; i++) { 23 | int a, b, t, k; 24 | cin >> a >> b >> t >> k; 25 | --a, --b; 26 | 27 | g.add_directed_edge(a, b, { t, k }); 28 | g.add_directed_edge(b, a, { t, k }); 29 | } 30 | 31 | using PathWeight = int64_t; 32 | 33 | auto JoinPathAndEdge = [](PathWeight path, EdgeWeight edge) { 34 | return (path + edge.k - 1) / edge.k * edge.k + edge.t; 35 | }; 36 | 37 | auto PathWeightLessThan = less(); 38 | 39 | ShortestPathTree spt(g, {X}, 0, JoinPathAndEdge, PathWeightLessThan); 40 | 41 | cout << (spt.is_reachable(Y) ? spt.distance(Y) : -1) << endl; 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /numeric/fft.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | const int FFT_CUTOFF = 150; 6 | 7 | template 8 | void fft(RandomAccessIterator first, RandomAccessIterator last, bool invert) { 9 | int N = int(last - first); 10 | assert(__builtin_popcount(N) == 1); 11 | 12 | for (int i = 1, j = 0, k; i < N; i++) { 13 | for (k = N >> 1; (j ^= k) < k; k >>= 1); 14 | if (i < j) std::swap(first[i], first[j]); 15 | } 16 | 17 | using T = typename std::remove_reference::type; 18 | 19 | for (int l = 1; l < N; l <<= 1) { 20 | for (int i = 0; i < N; i += 2 * l) { 21 | for (int j = 0; j < l; j++) { 22 | T w = T::unity_root(2 * l, invert ? -j : j); 23 | T u = first[i + j]; 24 | T v = first[i + j + l] * w; 25 | first[i + j] = u + v; 26 | first[i + j + l] = u - v; 27 | } 28 | } 29 | } 30 | 31 | if (invert) { 32 | T N_inverse = T{N}.inv(); 33 | 34 | for (int i = 0; i < N; i++) 35 | first[i] = first[i] * N_inverse; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /graphs/strongly_connected_components.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct scc { 4 | int components; 5 | std::vector label; 6 | }; 7 | 8 | // Labels strongly connected components in reverse topological order. 9 | // That means for any edge u-->v label[u] >= label[v]. 10 | scc strongly_connected_components(const std::vector>& graph) { 11 | const int N = int(graph.size()); 12 | 13 | int C = 0, V = 0, top = 0; 14 | std::vector comp(N, -1), inx(N, -1), stack(N + 1, -1); 15 | 16 | auto tarjan = [&](auto&& self, int loc) -> int { 17 | stack[top++] = loc; 18 | int low = inx[loc] = V++; 19 | for (int nbr : graph[loc]) { 20 | if (inx[nbr] == -1) low = std::min(low, self(self, nbr)); 21 | else if (comp[nbr] == -1) low = std::min(low, inx[nbr]); 22 | } 23 | if (low == inx[loc]) { 24 | while (stack[top] != loc) 25 | comp[stack[--top]] = C; 26 | C++; 27 | } 28 | return low; 29 | }; 30 | 31 | for (int i = 0; i < N; i++) { 32 | if (inx[i] == -1) 33 | tarjan(tarjan, i); 34 | } 35 | return { C, comp }; 36 | } 37 | -------------------------------------------------------------------------------- /data_structures/splitmix64_hash_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // https://codeforces.com/blog/entry/62393 5 | 6 | struct sp64_hash { 7 | static uint64_t splitmix64(uint64_t x) { 8 | x += 0x9e3779b97f4a7c15; 9 | x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; 10 | x = (x ^ (x >> 27)) * 0x94d049bb133111eb; 11 | return x ^ (x >> 31); 12 | } 13 | 14 | static uint64_t random_address() { char *p = new char; delete p; return uint64_t(p); } 15 | 16 | size_t operator()(uint64_t x) const { 17 | static const uint64_t FIXED_RANDOM = splitmix64((random_address() | 1) 18 | * std::chrono::steady_clock::now().time_since_epoch().count()); 19 | return splitmix64(x ^ FIXED_RANDOM); 20 | } 21 | }; 22 | 23 | template 24 | struct sp64_pair_hash { 25 | size_t operator()(const std::pair& x) const { 26 | static_assert(sizeof(K) <= 4, "type K has size exceeding 32 bits"); 27 | static sp64_hash sp64; 28 | return sp64(((uint64_t) x.first << 32) ^ x.second); 29 | } 30 | }; 31 | 32 | template 33 | using umap = __gnu_pbds::gp_hash_table; 34 | -------------------------------------------------------------------------------- /graphs/digraph_reachability.cpp: -------------------------------------------------------------------------------- 1 | // {{{ graphs/strongly_connected_components.cpp }}} 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | template 10 | std::vector> digraph_reachability( 11 | const std::vector> &graph) { 12 | int V = int(graph.size()); 13 | assert(V <= MAXV); 14 | 15 | scc s = strongly_connected_components(graph); 16 | 17 | std::vector> component_reachability(s.components); 18 | 19 | for (int v = 0; v < s.components; v++) 20 | component_reachability[s.label[v]][v] = true; 21 | 22 | std::vector order; 23 | std::iota(order.begin(), order.end(), 0); 24 | sort(order.begin(), order.end(), 25 | [&](int u, int v) { return s.label[u] < s.label[v]; }); 26 | 27 | for (int u : order) 28 | for (int v : graph[u]) 29 | component_reachability[s.label[u]] 30 | |= component_reachability[s.label[v]]; 31 | 32 | std::vector> reach(V); 33 | for (int v = 0; v < V; v++) 34 | reach[v] = component_reachability[s.label[v]]; 35 | return reach; 36 | } 37 | -------------------------------------------------------------------------------- /test/data_structures/line_container_monotonic/the_fair_nut_and_rectangles/the_fair_nut_and_rectangles.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://codeforces.com/contest/1083/problem/E 2 | 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | // {{{ data_structures/line_container_monotonic }}} 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(0); 13 | 14 | int N; 15 | cin >> N; 16 | 17 | struct rectangle { 18 | int x, y; 19 | int64_t c; 20 | }; 21 | 22 | vector rect(N); 23 | 24 | for (auto &[x, y, c] : rect) 25 | cin >> x >> y >> c; 26 | 27 | sort(rect.begin(), rect.end(), [](rectangle a, rectangle b) { 28 | return a.x < b.x; 29 | }); 30 | 31 | line_container_monotonic lc; 32 | 33 | lc.insert_line(0, 0); 34 | 35 | int64_t ans = 0; 36 | 37 | size_t position = 0; 38 | 39 | for (auto [x, y, c] : rect) { 40 | int64_t best = int64_t(x) * y - c + lc.get_maximum_monotonic(-y, position); 41 | 42 | ans = max(ans, best); 43 | 44 | lc.insert_line(x, best); 45 | } 46 | 47 | cout << ans << endl; 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /test/data_structures/union_find/roads_not_only_in_berland/roads_not_only_in_berland.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://codeforces.com/contest/25/problem/D 2 | 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | // {{{ data_structures/union_find }}} 9 | 10 | int main() { 11 | int N; 12 | scanf("%d", &N); 13 | 14 | union_find uf(N); 15 | 16 | std::vector> redundant; 17 | 18 | for (int i = 0; i < N - 1; i++) { 19 | int u, v; 20 | scanf("%d %d", &u, &v); 21 | --u, --v; 22 | 23 | if (!uf.unite(u, v)) 24 | redundant.emplace_back(u, v); 25 | } 26 | 27 | std::vector component_roots; 28 | 29 | for (int i = 0; i < N; i++) 30 | if (uf.is_root(i)) 31 | component_roots.push_back(i); 32 | 33 | assert(redundant.size() + 1 == component_roots.size()); 34 | 35 | printf("%d\n", int(redundant.size())); 36 | 37 | for (int i = 0; i < int(redundant.size()); i++) { 38 | printf("%d %d %d %d\n", 39 | redundant[i].first + 1, redundant[i].second + 1, 40 | component_roots[i] + 1, component_roots[i + 1] + 1); 41 | } 42 | 43 | return 0; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree/point_set_range_composite/point_set_range_composite.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://judge.yosupo.jp/problem/point_set_range_composite 2 | 3 | // {{{ numeric/modnum.cpp }}} 4 | 5 | // {{{ data_structures/segment_tree.cpp }}} 6 | 7 | using mn = modnum<998244353>; 8 | 9 | int main() { 10 | int N, Q; 11 | scanf("%d %d", &N, &Q); 12 | 13 | struct func { 14 | mn a, b; 15 | mn eval(int x) { return a * x + b; } 16 | }; 17 | 18 | // g(f(x)) 19 | auto compose = [](func f, func g) { 20 | return func { 21 | f.a * g.a, 22 | f.b * g.a + g.b 23 | }; 24 | }; 25 | 26 | segment_tree s(N, {1, 0}, compose); 27 | 28 | s.assign([](int i) { int a, b; scanf("%d %d", &a, &b); return func{a, b}; }); 29 | 30 | for (int q = 0; q < Q; q++) { 31 | int t; 32 | scanf("%d", &t); 33 | if (t == 0) { 34 | int p, c, d; 35 | scanf("%d %d %d", &p, &c, &d); 36 | s.assign(p, func{c, d}); 37 | } else { 38 | int l, r, x; 39 | scanf("%d %d %d", &l, &r, &x); 40 | printf("%d\n", s.accumulate(l, r).eval(x)); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test/strings/trie/minimum_length_substring_with_k_occurrences/minimum_length_substring_with_k_occurrences.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://codeforces.com/contest/963/problem/D 2 | 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // {{{ strings/trie.cpp }}} 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(0); 11 | cin.tie(nullptr); 12 | 13 | string s; 14 | cin >> s; 15 | 16 | int Q; 17 | cin >> Q; 18 | 19 | vector k(Q); 20 | vector m(Q); 21 | 22 | for (int q = 0; q < Q; q++) { 23 | cin >> k[q] >> m[q]; 24 | } 25 | 26 | trie<'a', 26> tr(m.begin(), m.end()); 27 | 28 | vector> occur = tr.indices_of_matches(s.begin(), s.end()); 29 | 30 | for (int q = 0; q < Q; q++) { 31 | if (int(occur[q].size()) < k[q]) { 32 | cout << -1 << "\n"; 33 | continue; 34 | } 35 | 36 | int ans = int(s.size()); 37 | 38 | for (int f = 0; f <= int(occur[q].size()) - k[q]; f++) { 39 | int begin = occur[q][f]; 40 | int end = occur[q][f + k[q] - 1] + int(m[q].size()); 41 | 42 | ans = min(ans, end - begin); 43 | } 44 | 45 | cout << ans << "\n"; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /graphs/breadth_first_search.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct BFS { 5 | std::vector distance; 6 | std::vector parent; 7 | 8 | BFS(const std::vector> &adj, const std::vector &sources) { 9 | const int n = adj.size(); 10 | distance.assign(n, -1); 11 | parent.assign(n, -1); 12 | 13 | std::queue q; 14 | for (int i : sources) { 15 | q.push(i); 16 | distance[i] = 0; 17 | } 18 | 19 | while (!q.empty()) { 20 | int i = q.front(); 21 | q.pop(); 22 | 23 | for (int j : adj[i]) { 24 | if (distance[j] != -1) 25 | continue; 26 | 27 | q.push(j); 28 | distance[j] = distance[i] + 1; 29 | parent[j] = i; 30 | } 31 | } 32 | } 33 | 34 | std::vector get_path(int destination) { 35 | if (distance[destination] == -1) 36 | return {}; 37 | std::vector path{}; 38 | for (int i = destination; i != -1; i = parent[i]) 39 | path.push_back(i); 40 | std::reverse(path.begin(), path.end()); 41 | return path; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /test/data_structures/static_to_dynamic_transformation/string_set_queries/string_set_queries.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://codeforces.com/problemset/problem/710/F 2 | 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // {{{ strings/trie }}} 8 | 9 | // {{{ data_structures/static_to_dynamic_transformation }}} 10 | 11 | int main() { 12 | ios_base::sync_with_stdio(false); 13 | cin.tie(nullptr); 14 | 15 | static_to_dynamic_transformation> 16 | inserted, deleted; 17 | 18 | int Q; 19 | cin >> Q; 20 | 21 | for (int q = 0; q < Q; q++) { 22 | int type; 23 | string str; 24 | cin >> type >> str; 25 | 26 | if (type == 1) 27 | inserted.insert(str); 28 | else if (type == 2) 29 | deleted.insert(str); 30 | else { 31 | auto query = [&](const trie<'a', 26> &tr) { 32 | return int(tr.count_total_matches(str.begin(), str.end())); 33 | }; 34 | 35 | int inserted_matches = inserted.accumulate(query, 0, plus()); 36 | int deleted_matches = deleted.accumulate(query, 0, plus()); 37 | 38 | cout << inserted_matches - deleted_matches << endl; 39 | } 40 | } 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /test/graphs/heavy_path_decomposition/vertex_add_path_sum/vertex_add_path_sum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // {{{ graphs/heavy_path_decomposition.cpp }}} 5 | // {{{ data_structures/binary_indexed_tree.cpp }}} 6 | 7 | int main() { 8 | int N, Q; 9 | scanf("%d %d", &N, &Q); 10 | 11 | std::vector init(N); 12 | for (int i = 0; i < N; i++) 13 | scanf("%d", &init[i]); 14 | 15 | tree tr(N, 0); 16 | re(tr, EDGE_LIST, 0); 17 | 18 | heavy_path_decomposition hld(tr); 19 | 20 | binary_indexed_tree> bit(N, 0, std::plus()); 21 | 22 | for (int i = 0; i < N; i++) 23 | bit.add(hld.index(i), init[i]); 24 | 25 | for (int q = 0; q < Q; q++) { 26 | int t; 27 | scanf("%d", &t); 28 | 29 | if (t == 0) { 30 | int p, x; 31 | scanf("%d %d", &p, &x); 32 | bit.add(hld.index(p), x); 33 | } else { 34 | int u, v; 35 | scanf("%d %d", &u, &v); 36 | printf("%jd\n", hld.accumulate_commutative(u, v, true, int64_t(0), std::plus(), 37 | [&bit](uint32_t i, uint32_t j) { return bit.accumulate_prefix(j) - bit.accumulate_prefix(i); })); 38 | } 39 | } 40 | 41 | return 0; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /test/graphs/tree/weighted_tree_diameter/weighted_tree_diameter.cpp: -------------------------------------------------------------------------------- 1 | // {{{ graphs/tree.cpp }}} 2 | 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | int main() { 8 | ios::sync_with_stdio(false); 9 | cin.tie(nullptr); 10 | 11 | int N; 12 | cin >> N; 13 | 14 | using E = edge_with_data; 15 | 16 | tree t(N, 0); 17 | 18 | re(t, EDGE_LIST, 0, [](E &e) { cin >> e.data; }); 19 | 20 | vector dist0(N); 21 | for (int u : t.preorder) 22 | t.for_each_child(u, [&](E e) { dist0[e.get_nbr(u)] = dist0[u] + e.data; }); 23 | 24 | int x = int(max_element(dist0.begin(), dist0.end()) - dist0.begin()); 25 | 26 | t.reroot(x); 27 | 28 | vector distx(N); 29 | for (int u : t.preorder) 30 | t.for_each_child(u, [&](E e) { distx[e.get_nbr(u)] = distx[u] + e.data; }); 31 | 32 | int y = int(max_element(distx.begin(), distx.end()) - distx.begin()); 33 | 34 | cout << distx[y]; 35 | 36 | vector path = {y}; 37 | while (y != x) { 38 | y = t.parent[y]; 39 | path.push_back(y); 40 | } 41 | 42 | cout << " " << path.size() << "\n"; 43 | 44 | for (int i = 0; i < int(path.size()); i++) { 45 | if (i) cout << " "; 46 | cout << path[i]; 47 | } 48 | cout << "\n"; 49 | } 50 | -------------------------------------------------------------------------------- /data_structures/monotonic_queue.cpp: -------------------------------------------------------------------------------- 1 | // {{{ data_structures/monotonic_stack }}} 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | template > 8 | struct monotonic_queue { 9 | monotonic_stack in, out; 10 | LessThan less_than; 11 | 12 | public: 13 | bool empty() const { return in.empty() && out.empty(); } 14 | int size() const { return in.size() + out.size(); } 15 | T front() { 16 | assert(!empty()); 17 | refill(); 18 | return out.top(); 19 | } 20 | 21 | void push(const T &item) { in.push(item); } 22 | 23 | void pop() { 24 | assert(!empty()); 25 | refill(); 26 | out.pop(); 27 | } 28 | 29 | T min() const { 30 | assert(!empty()); 31 | if (in.empty()) 32 | return out.min(); 33 | if (out.empty()) 34 | return in.min(); 35 | return std::min(in.min(), out.min(), less_than); 36 | } 37 | 38 | T min(const T &default_value) const { return empty() ? default_value : min(); } 39 | 40 | private: 41 | void refill() { 42 | if (!out.empty()) 43 | return; 44 | while (!in.empty()) { 45 | out.push(in.top()); 46 | in.pop(); 47 | } 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /test/numeric/bignum_addpow2_compare/the_classic_problem/the_classic_problem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // {{{ numeric/bignum_addpow2_compare }}} 5 | 6 | // {{{ graphs/dijkstra }}} 7 | 8 | int main() { 9 | ios_base::sync_with_stdio(false); 10 | cin.tie(0); 11 | 12 | int N, M; 13 | cin >> N >> M; 14 | 15 | WeightedDirectedGraph g(N); 16 | 17 | for (int e = 0; e < M; e++) { 18 | int u, v, w; 19 | cin >> u >> v >> w; 20 | --u, --v; 21 | 22 | g.add_directed_edge(u, v, w); 23 | g.add_directed_edge(v, u, w); 24 | } 25 | 26 | int S, T; 27 | cin >> S >> T; 28 | --S, --T; 29 | 30 | bignum_addpow2_compare nums; 31 | 32 | ShortestPathTree sp(g, {S}, 0, 33 | [&](int path, int edge) { return nums.add_pow2(path, edge); }, 34 | [&](int a, int b) { return nums.less_than(a, b); } 35 | ); 36 | 37 | if (!sp.is_reachable(T)) { 38 | cout << -1 << endl; 39 | return 0; 40 | } 41 | 42 | int dist = sp.distance(T); 43 | vector path = sp.list_vertices_on_path(T); 44 | 45 | cout << nums.nums[dist].hash.data[0] << endl; 46 | 47 | cout << path.size() << endl; 48 | 49 | for (int v : path) 50 | cout << v + 1 << " "; 51 | cout << endl; 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /test/strings/polynomial_hash/good_substrings/good_substrings.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://codeforces.com/contest/271/problem/D 2 | 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // {{{ strings/polynomial_hash.cpp }}} 8 | 9 | int main() { 10 | ios_base::sync_with_stdio(false); 11 | cin.tie(nullptr); 12 | 13 | string s; 14 | cin >> s; 15 | 16 | array good; 17 | for (int i = 0; i < 26; i++) { 18 | char c; 19 | cin >> c; 20 | good[i] = c == '1'; 21 | } 22 | 23 | int K; 24 | cin >> K; 25 | 26 | using H = polynomial_hash, 5, 256>; 27 | 28 | vector s_prefixes = H::get_prefixes(s.begin(), s.end()); 29 | 30 | vector good_substrings; 31 | 32 | for (int head = 0; head < int(s.size()); head++) { 33 | int bad = 0; 34 | for (int tail = head; tail < int(s.size()); tail++) { 35 | if (!good[s[tail] - 'a']) 36 | bad++; 37 | 38 | if (bad > K) 39 | break; 40 | 41 | good_substrings.push_back(H::get_substring(s_prefixes, head, tail + 1)); 42 | } 43 | } 44 | 45 | sort(good_substrings.begin(), good_substrings.end()); 46 | 47 | cout << unique(good_substrings.begin(), good_substrings.end()) - good_substrings.begin() << endl; 48 | } 49 | -------------------------------------------------------------------------------- /test/misc/subset_sum/polandball_and_gifts/polandball_and_gifts.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://codeforces.com/problemset/problem/755/F 2 | 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | // {{{ misc/subset_sum.cpp }}} 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(0); 13 | 14 | int N, K; 15 | cin >> N >> K; 16 | 17 | vector giver(N); 18 | 19 | for (int i = 0; i < N; i++) { 20 | cin >> giver[i]; 21 | --giver[i]; 22 | } 23 | 24 | vector cycle_lengths; 25 | 26 | vector visited(N); 27 | for (int i = 0; i < N; i++) { 28 | if (visited[i]) 29 | continue; 30 | 31 | int length = 0; 32 | for (int t = i; !visited[t]; t = giver[t]) { 33 | visited[t] = true; 34 | length++; 35 | } 36 | 37 | cycle_lengths.push_back(length); 38 | } 39 | 40 | auto sums = subset_sum<1000000>(cycle_lengths.begin(), cycle_lengths.end()); 41 | 42 | int minimum = K + !sums[K]; 43 | 44 | int twos = 0, ones = 0; 45 | 46 | for (int length : cycle_lengths) { 47 | twos += length / 2; 48 | ones += length & 1; 49 | } 50 | 51 | int maximum = 2 * min(K, twos) + min(ones, K - min(K, twos)); 52 | 53 | printf("%d %d\n", minimum, maximum); 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /numeric/tonelli-shanks.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int product(int x, int y, int MOD) { 5 | return int(int64_t(x) * y % MOD); 6 | } 7 | 8 | int mod_pow(int x, int k, int MOD) { 9 | if (!k) return 1; 10 | if (k&1) return product(x, mod_pow(x, k - 1, MOD), MOD); 11 | return mod_pow(product(x, x, MOD), k / 2, MOD); 12 | } 13 | 14 | /* 15 | * Tonelli–Shanks algorithm: finds some r such that r*r = n (MOD). 16 | * MOD should be a prime power. 17 | * Returns -1 if no such r exists. 18 | */ 19 | int sqrt(int n, int MOD) { 20 | assert(0 <= n && n < MOD); 21 | 22 | if (n == 0) return 0; 23 | if (MOD == 2) return n; 24 | if (mod_pow(n, (MOD - 1) >> 1, MOD) != 1) return -1; 25 | 26 | int Q = MOD - 1, S = 0; 27 | while (!(Q&1)) Q >>= 1, S++; 28 | 29 | int z = 2; 30 | while (mod_pow(z, (MOD - 1) >> 1, MOD) == 1) z++; 31 | z = mod_pow(z, Q, MOD); 32 | assert(mod_pow(z, 1 << (S - 1), MOD) == MOD - 1); 33 | 34 | int r = mod_pow(n, (Q + 1) >> 1, MOD), 35 | t = mod_pow(n, Q, MOD); 36 | 37 | for (int m = S - 2; t != 1; m--) { 38 | int nz = product(z, z, MOD); 39 | if (mod_pow(t, 1 << m, MOD) != 1) { 40 | r = product(r, z, MOD); 41 | t = product(t, nz, MOD); 42 | } 43 | z = nz; 44 | } 45 | 46 | assert(product(r, r, MOD) == n); 47 | return r; 48 | } 49 | -------------------------------------------------------------------------------- /data_structures/sparse_table.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | struct sparse_table { 6 | int SZ; 7 | IdempotentBinaryOperation TT; 8 | std::vector> data; 9 | 10 | sparse_table() {} 11 | 12 | sparse_table(IdempotentBinaryOperation _TT) : TT(_TT) {} 13 | 14 | template 15 | sparse_table(int _SZ, IdempotentBinaryOperation _TT, Function fn) : TT(_TT) { 16 | construct(_SZ, fn); 17 | } 18 | 19 | template 20 | void construct(int _SZ, Function fn) { 21 | SZ = _SZ; 22 | 23 | const int L = 32 - __builtin_clz(std::max(SZ - 1, 1)); 24 | data.assign(L, std::vector(SZ)); 25 | 26 | for (int i = 0; i < SZ; i++) 27 | data[0][i] = fn(i); 28 | 29 | for (int l = 0; l + 1 < L; l++) 30 | for (int i = 0; i + (2 << l) <= SZ; i++) 31 | data[l + 1][i] = TT(data[l][i], data[l][i + (1 << l)]); 32 | } 33 | 34 | // Accumulates the elements at indices in [i, j) in O(1) 35 | T accumulate(int first, int last) const { 36 | assert(0 <= first && first < last && last <= SZ); 37 | int l = last - first > 1 ? 31 - __builtin_clz(last - first - 1) : 0; 38 | return TT(data[l][first], data[l][last - (1 << l)]); 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /graphs/poset_width.cpp: -------------------------------------------------------------------------------- 1 | vi width(vector poset) { 2 | int N = poset.size(); 3 | bipartite_graph g(N, N); 4 | 5 | for (int i = 0; i < N; i++) { 6 | for (int j : poset[i]) 7 | g.edge(j, i); 8 | } 9 | 10 | g.matching(); 11 | 12 | vb vis[2]; 13 | vis[false].resize(2 * N, false); 14 | vis[true].resize(2 * N, false); 15 | 16 | for (int i = 0; i < N; i++) { 17 | if (g.match[i] != -1) continue; 18 | if (vis[false][i]) continue; 19 | 20 | queue> bfs; 21 | bfs.push(make_pair(false, i)); 22 | vis[false][i] = true; 23 | 24 | while (!bfs.empty()) { 25 | bool inm = bfs.front().first; 26 | int loc = bfs.front().second; 27 | bfs.pop(); 28 | 29 | for (int nbr : g.adj[loc]) { 30 | if (vis[!inm][nbr]) continue; 31 | if ((g.match[loc] == nbr) ^ inm) continue; 32 | 33 | vis[!inm][nbr] = true; 34 | bfs.push(make_pair(!inm, nbr)); 35 | } 36 | } 37 | } 38 | 39 | vb inz(2 * N, false); 40 | for (int i = 0; i < 2 * N; i++) 41 | inz[i] = vis[true][i] || vis[false][i]; 42 | 43 | vb ink(N, false); 44 | 45 | for (int i = 0; i < N; i++) 46 | if (!inz[i]) 47 | ink[i]= true; 48 | 49 | for (int i = N; i < 2 * N; i++) 50 | if (inz[i]) 51 | ink[i - N] = true; 52 | 53 | vi res; 54 | for (int i = 0; i < N; i++) { 55 | if (!ink[i]) 56 | res.push_back(i); 57 | } 58 | return res; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /test/data_structures/line_container_monotonic/cats_transport/cats_transport.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://codeforces.com/contest/311/problem/B 2 | 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | // {{{ data_structures/line_container_monotonic }}} 9 | 10 | int main() { 11 | ios_base::sync_with_stdio(false); 12 | cin.tie(0); 13 | 14 | int N, M, P; 15 | cin >> N >> M >> P; 16 | 17 | vector dist(N); 18 | 19 | for (int i = 0; i < N - 1; i++) { 20 | int d; 21 | cin >> d; 22 | 23 | dist[i + 1] = dist[i] + d; 24 | } 25 | 26 | vector cats(M); 27 | 28 | for (int i = 0; i < M; i++) { 29 | int h, t; 30 | cin >> h >> t; 31 | cats[i] = t - dist[h - 1]; 32 | } 33 | 34 | sort(cats.begin(), cats.end()); 35 | 36 | vector prefixes(M + 1); 37 | 38 | for (int i = 0; i < M; i++) 39 | prefixes[i + 1] = prefixes[i] + cats[i]; 40 | 41 | line_container_monotonic prev, next; 42 | 43 | prev.insert_line(0, 0); 44 | 45 | int64_t cost; 46 | 47 | for (int handler = 0; handler < P; handler++) { 48 | size_t position = 0; 49 | for (int take = 1; take <= M; take++) { 50 | cost = take * int64_t(cats[take - 1]) 51 | - prefixes[take] 52 | - prev.get_maximum_monotonic(cats[take - 1], position); 53 | 54 | next.insert_line(take, -cost - prefixes[take]); 55 | } 56 | 57 | swap(prev, next); 58 | next.clear(); 59 | } 60 | 61 | cout << cost << endl; 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /test/data_structures/segment_tree_lazy/range_add_range_min/range_add_range_min.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://codeforces.com/contest/52/problem/C 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | // {{{ data_structures/segment_tree_lazy }}} 11 | 12 | int main() { 13 | int N; 14 | scanf("%d", &N); 15 | 16 | using std_min_type = const int64_t&(*)(const int64_t&, const int64_t&); 17 | 18 | segment_tree_lazy, plus> 19 | st(N, 1e12, 0, min, plus(), plus()); 20 | 21 | st.assign([](int i) { int v; scanf("%d", &v); return v; }); 22 | 23 | int Q; 24 | scanf("%d\n", &Q); 25 | 26 | char s[256]; 27 | 28 | for (int q = 0; q < Q; q++) { 29 | fgets(s, 256, stdin); 30 | 31 | char *p = strtok(s, " "); 32 | int lf = atoi(p); 33 | 34 | p = strtok(NULL, " "); 35 | int rg = atoi(p); 36 | 37 | p = strtok(NULL, " "); 38 | if (p != NULL) { 39 | int v = atoi(p); 40 | if (lf <= rg) { 41 | st.apply_update(lf, rg + 1, v); 42 | } else { 43 | st.apply_update(lf, N, v); 44 | st.apply_update(0, rg + 1, v); 45 | } 46 | } else { 47 | int64_t res; 48 | if (lf <= rg) 49 | res = st.accumulate(lf, rg + 1); 50 | else 51 | res = min(st.accumulate(lf, N), st.accumulate(0, rg + 1)); 52 | printf("%jd\n", res); 53 | } 54 | } 55 | 56 | return 0; 57 | } 58 | 59 | -------------------------------------------------------------------------------- /test/data_structures/union_find_bipartite/prefix_enlightenment/prefix_enlightenment.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://codeforces.com/problemset/problem/1290/C 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | // {{{ data_structures/union_find_bipartite }}} 10 | 11 | int main() { 12 | ios_base::sync_with_stdio(false); 13 | cin.tie(nullptr); 14 | 15 | int N, K; 16 | cin >> N >> K; 17 | 18 | string s; 19 | cin >> s; 20 | 21 | vector> switches(N); 22 | 23 | for (int sw = 0; sw < K; sw++) { 24 | int C; 25 | cin >> C; 26 | for (int i = 0; i < C; i++) { 27 | int e; 28 | cin >> e; 29 | switches[e - 1].push_back(sw); 30 | } 31 | } 32 | 33 | union_find_bipartite uf(K); 34 | 35 | for (int lamp = 0; lamp < N; lamp++) { 36 | switch (switches[lamp].size()) { 37 | case 0: 38 | assert(s[lamp] == '1'); 39 | break; 40 | case 1: 41 | assert(uf.can_constrain_node_to_side(switches[lamp][0], s[lamp] != '1')); 42 | assert(uf.constrain_node_to_side(switches[lamp][0], s[lamp] != '1')); 43 | break; 44 | case 2: 45 | assert(uf.can_add_constraint_on_nodes(switches[lamp][0], switches[lamp][1], s[lamp] != '1')); 46 | assert(uf.unite(switches[lamp][0], switches[lamp][1], s[lamp] != '1').component_is_bipartite); 47 | break; 48 | default: 49 | assert(false); 50 | } 51 | 52 | cout << uf.min_nodes_on_side_1 << "\n"; 53 | } 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /data_structures/segment_tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | struct segment_tree { 6 | int SZ; 7 | T identity; 8 | AssociativeOperation TT; 9 | std::vector data; 10 | 11 | segment_tree() {} 12 | 13 | segment_tree(int _SZ, T _identity, AssociativeOperation _TT) 14 | : SZ(_SZ), identity(_identity), TT(_TT) { 15 | data.resize(2 * SZ, identity); 16 | } 17 | 18 | // Returns the value at index i 19 | const T& operator[](int i) const { 20 | assert(0 <= i && i < SZ); 21 | return data[SZ + i]; 22 | } 23 | 24 | // Assigns fn(i) at index i for each i in [0, SZ) 25 | template 26 | void assign(Function fn) { 27 | for (int i = 0; i < SZ; i++) 28 | data[SZ + i] = fn(i); 29 | for (int i = SZ - 1; i; i--) 30 | data[i] = TT(data[2 * i], data[2 * i + 1]); 31 | } 32 | 33 | // Assigns v at index i 34 | void assign(int i, T v) { 35 | assert(0 <= i && i < SZ); 36 | data[i += SZ] = v; 37 | for (i /= 2; i; i /= 2) 38 | data[i] = TT(data[2 * i], data[2 * i + 1]); 39 | } 40 | 41 | // Returns the result of a left fold of the elements at indices in [first, last) over TT 42 | T accumulate(int first, int last) const { 43 | assert(0 <= first && last <= SZ); 44 | T left = identity, right = identity; 45 | for (first += SZ, last += SZ; first < last; first /= 2, last /= 2) { 46 | if (first & 1) left = TT(left, data[first++]); 47 | if (last & 1) right = TT(data[--last], right); 48 | } 49 | return TT(left, right); 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /graphs/bipartite_graph.cpp: -------------------------------------------------------------------------------- 1 | struct bipartite_graph { 2 | int A, B; 3 | vvi adj; 4 | 5 | bipartite_graph(int _A, int _B) { 6 | A = _A, B = _B; 7 | adj.resize(A + B); 8 | } 9 | 10 | void edge(int i, int j) { 11 | adj[i].push_back(A+j); 12 | adj[A+j].push_back(i); 13 | } 14 | 15 | vi visit, match; 16 | 17 | bool augment(int loc, int run) { 18 | if(visit[loc] == run) return false; 19 | visit[loc] = run; 20 | 21 | for (int nbr : adj[loc]) { 22 | if (match[nbr] == -1 || augment(match[nbr], run)) { 23 | match[loc] = nbr, match[nbr] = loc; 24 | return true; 25 | } 26 | } 27 | 28 | return false; 29 | } 30 | 31 | int matching() { 32 | visit = vi(A+B, -1); 33 | match = vi(A+B, -1); 34 | 35 | int ans = 0; 36 | for (int i = 0; i < A; i++) 37 | ans += augment(i, i); 38 | return ans; 39 | } 40 | 41 | vector vertex_cover() { 42 | vector res(A + B, false); 43 | queue bfs; 44 | 45 | for (int i = 0; i < A; i++) { 46 | if (match[i] == -1) bfs.push(i); 47 | else res[i] = true; 48 | } 49 | 50 | while (!bfs.empty()) { 51 | int loc = bfs.front(); 52 | bfs.pop(); 53 | for (int nbr : adj[loc]) { 54 | if (res[nbr]) continue; 55 | res[nbr] = true; 56 | int loc2 = match[nbr]; 57 | if (loc2 == -1) continue; 58 | res[loc2] = false; 59 | bfs.push(loc2); 60 | } 61 | } 62 | 63 | return res; 64 | } 65 | }; 66 | 67 | -------------------------------------------------------------------------------- /strings/mutable_string_bitset.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #pragma GCC optimize("unroll-loops") 5 | #pragma GCC target("popcnt,tune=native") 6 | 7 | template 8 | struct mutable_string_bitset { 9 | std::vector> occur; 10 | 11 | template 12 | mutable_string_bitset(InputIterator first, InputIterator last) : occur(SIGMA) { 13 | int i = 0; 14 | for (InputIterator iter = first; iter != last; iter++) 15 | occur[*iter - MIN_CHAR][i++] = true; 16 | } 17 | 18 | void assign(int i, int c) { 19 | for (int a = 0; a < SIGMA; a++) 20 | occur[a][i] = false; 21 | occur[c - MIN_CHAR][i] = true; 22 | } 23 | 24 | /* Counts occurrences of the pattern [first, last) within the substring [L, R) 25 | * O(|last - first| * MAX_LEN / MACHINE_WORD_SIZE) 26 | */ 27 | template 28 | int count_matches(InputIterator first, InputIterator last, int L = 0, int R = MAX_LEN) const { 29 | static std::bitset match; 30 | match.set(); // sets all bits to true 31 | 32 | int i = 0; 33 | for (InputIterator iter = first; iter != last; iter++) 34 | match &= occur[*iter - MIN_CHAR] >> (i++); 35 | 36 | int count = 0; 37 | 38 | int min_pos = L, max_pos = R - i + 1; 39 | 40 | while (min_pos < max_pos && min_pos % 64) 41 | count += match[min_pos++]; 42 | 43 | while (min_pos < max_pos && max_pos % 64) 44 | count += match[--max_pos]; 45 | 46 | static uint64_t *data = (uint64_t*)&match; 47 | for (int inx = min_pos / 64; inx < max_pos / 64; inx++) 48 | count += __builtin_popcountll(data[inx]); 49 | 50 | return count; 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /numeric/ntt.cpp: -------------------------------------------------------------------------------- 1 | // {{{ numeric/modnum.cpp }}} 2 | // {{{ numeric/fft.cpp }}} 3 | 4 | #include 5 | #include 6 | 7 | namespace ntt { 8 | template 9 | std::vector> operator*(std::vector> a, std::vector> b) { 10 | if (a.empty() || b.empty()) return {}; 11 | int s = int(a.size()) + int(b.size()) - 1; 12 | if (std::min(a.size(), b.size()) < FFT_CUTOFF) { 13 | const vv_t VV_BOUND = std::numeric_limits::max() - vv_t(MOD) * MOD; 14 | std::vector res(s); 15 | for (int i = 0; i < int(a.size()); i++) { 16 | for (int j = 0; j < int(b.size()); j++) { 17 | res[i + j] += vv_t(a[i].v) * b[j].v; 18 | if (res[i + j] > VV_BOUND) 19 | res[i + j] %= MOD; 20 | } 21 | } 22 | return {res.begin(), res.end()}; 23 | } 24 | 25 | int N = 1 << (s > 1 ? 32 - __builtin_clz(s - 1) : 0); 26 | 27 | bool eq = a == b; 28 | a.resize(N); 29 | fft(a.begin(), a.end(), false); 30 | 31 | if (!eq) { 32 | b.resize(N); 33 | fft(b.begin(), b.end(), false); 34 | for (int i = 0; i < N; i++) a[i] *= b[i]; 35 | } else { 36 | for (int i = 0; i < N; i++) a[i] *= a[i]; 37 | } 38 | 39 | fft(a.begin(), a.end(), true); 40 | a.resize(s); 41 | return a; 42 | } 43 | 44 | template 45 | std::vector> pow(std::vector> v, int p) { 46 | std::vector> r = {1}; 47 | if (!p) return r; 48 | for (int i = 31 - __builtin_clz(p); i >= 0; --i) { 49 | r = r * r; 50 | if (p & (1 << i)) r = r * v; 51 | } 52 | return r; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /data_structures/union_find.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct union_find { 6 | struct node { 7 | int parent_or_size; 8 | node () : parent_or_size(-1) {} 9 | }; 10 | 11 | mutable std::vector data; 12 | 13 | union_find(int SZ = 0) : data(SZ) {} 14 | 15 | // Returns the root of the component containing i 16 | int find(int i) const { 17 | if (data[i].parent_or_size < 0) 18 | return i; 19 | data[i].parent_or_size = find(data[i].parent_or_size); 20 | return data[i].parent_or_size; 21 | } 22 | 23 | int size(int i) const { 24 | return -data[find(i)].parent_or_size; 25 | } 26 | 27 | bool is_root(int i) const { 28 | return data[i].parent_or_size < 0; 29 | } 30 | 31 | node& operator[] (int i) const { 32 | return data[find(i)]; 33 | } 34 | 35 | /* Unites the components containing a and b if they are different. 36 | * Returns a boolean indicating whether a and b were in different components. 37 | */ 38 | bool unite(int a, int b) { 39 | a = find(a), b = find(b); 40 | if (a == b) return false; 41 | 42 | if (-data[a].parent_or_size < -data[b].parent_or_size) 43 | std::swap(a, b); 44 | 45 | data[a].parent_or_size += data[b].parent_or_size; 46 | data[b].parent_or_size = a; 47 | 48 | return true; 49 | } 50 | 51 | friend void pr(const union_find& u) { 52 | std::cout << "{"; 53 | bool first = 1; 54 | for (int i = 0; i < int(u.data.size()); i++) { 55 | if (u.is_root(i)) { 56 | if (!first) std::cout << ", "; 57 | else first = 0; 58 | std::cout << "[ " << i << " | size=" << u.size(i) << " ]"; 59 | } 60 | } 61 | std::cout << "}"; 62 | } 63 | }; 64 | -------------------------------------------------------------------------------- /data_structures/sqrt_decomposition_point_query.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | struct sqrt_decomposition_point_query { 6 | int SZ; 7 | T t_identity; 8 | CommutativeOperation TT; 9 | 10 | int SQRT; 11 | std::vector data; 12 | std::vector block_data; 13 | 14 | sqrt_decomposition_point_query() {} 15 | 16 | sqrt_decomposition_point_query(int _SZ, T _t_identity, CommutativeOperation _TT) 17 | : SZ(_SZ), t_identity(_t_identity), TT(_TT) { 18 | SQRT = 0; 19 | while (SQRT * SQRT < SZ) 20 | SQRT++; 21 | 22 | data.assign(SZ, t_identity); 23 | block_data.assign(SQRT, t_identity); 24 | } 25 | 26 | template 27 | void assign(Function fn) { 28 | for (int i = 0; i < SZ; i++) 29 | data[i] = fn(i); 30 | } 31 | 32 | public: 33 | // Replaces the current value at index i with TT(current value, v) 34 | void add(int i, T v) { 35 | data[i] = TT(data[i], v); 36 | } 37 | 38 | void add_to_range(int first, int last, T v) { 39 | if (last - first < SQRT) { 40 | for (int i = first; i < last; i++) 41 | data[i] = TT(data[i], v); 42 | return; 43 | } 44 | 45 | const int first_block = (first + SQRT - 1) / SQRT; 46 | const int last_block = last / SQRT; 47 | 48 | for (int i = first; i < first_block * SQRT; i++) 49 | data[i] = TT(data[i], v); 50 | 51 | for (int block = first_block; block < last_block; block++) 52 | block_data[block] = TT(block_data[block], v); 53 | 54 | for (int i = last_block * SQRT; i < last; i++) 55 | data[i] = TT(data[i], v); 56 | } 57 | 58 | // Returns the current value at index i 59 | T read(int i) const { 60 | return TT(data[i], block_data[i / SQRT]); 61 | } 62 | }; 63 | -------------------------------------------------------------------------------- /data_structures/line_container.cpp: -------------------------------------------------------------------------------- 1 | // {{{ data_structures/line }}} 2 | 3 | #include 4 | #include 5 | 6 | bool compare_on_intersection = false; 7 | 8 | template 9 | bool operator < (const line &p, const line &q) { 10 | if (compare_on_intersection) 11 | return p.intersects_next < q.intersects_next; 12 | 13 | return p.a != q.a ? p.a < q.a : p.b < q.b; 14 | } 15 | 16 | template 17 | struct line_container : std::set> { 18 | using typename std::set>::iterator; 19 | 20 | bool set_boundary(iterator left, iterator right) { 21 | if (right == this->end()) { 22 | left->intersects_next = line::infinity; 23 | return false; 24 | } 25 | 26 | left->intersects_next = left->compute_intersection(*right); 27 | return left->intersects_next >= right->intersects_next; 28 | } 29 | 30 | bool is_never_maximal(iterator y) { 31 | return y != this->begin() && set_boundary(prev(y), y); 32 | } 33 | 34 | // insert the line f(x) = a * x + b 35 | void insert_line(T a, T b) { 36 | auto [it, inserted] = this->insert({ a, b }); 37 | 38 | if (!inserted) 39 | return; 40 | 41 | while (set_boundary(it, next(it))) 42 | this->erase(next(it)); 43 | 44 | if (is_never_maximal(it)) { 45 | it = this->erase(it); 46 | set_boundary(prev(it), it); 47 | } 48 | 49 | while (it != this->begin() && is_never_maximal(prev(it))) { 50 | this->erase(prev(it)); 51 | set_boundary(prev(it), it); 52 | } 53 | } 54 | 55 | // returns the maximum value at x among all inserted lines 56 | T get_maximum(T x) { 57 | assert(!this->empty()); 58 | compare_on_intersection = true; 59 | T res = this->lower_bound({ 0, 0, x })->evaluate(x); 60 | compare_on_intersection = false; 61 | return res; 62 | } 63 | }; 64 | -------------------------------------------------------------------------------- /numeric/bitwise_convolution.cpp: -------------------------------------------------------------------------------- 1 | namespace bitwise_convolution { 2 | template void transform(vector& v, int N, array t) { 3 | assert(__builtin_popcount(N) == 1); 4 | for (int c : t) assert(abs(c) <= 1); 5 | int w = t[0], x = t[1], y = t[2], z = t[3]; 6 | if (INV) swap(w, z), x *= -1, y *= -1; 7 | 8 | auto prod = [](int c, T v){ return c > 0 ? v : c < 0 ? -v : 0; }; 9 | for (int l = 1; l < N; l <<= 1) { 10 | for (int i = 0; i < N; i += l << 1) { 11 | for (int j = 0; j < l; j++) { 12 | T a = v[i + j]; 13 | T b = v[i + j + l]; 14 | v[i + j] = prod(w, a) + prod(x, b); 15 | v[i + j + l] = prod(y, a) + prod(z, b); 16 | } 17 | } 18 | } 19 | if (INV) { 20 | const T dinv = 1 / T{w * z - x * y}.pow(__builtin_ctz(N)); 21 | for (int i = 0; i < N; i++) v[i] *= dinv; 22 | } 23 | } 24 | 25 | constexpr array OR(){ return {1,0,1,1}; } 26 | constexpr array AND(){ return {0,1,1,1}; } 27 | constexpr array XOR(){ return {1,1,1,-1}; } 28 | 29 | template 30 | vector conv(const vector& a, const vector& b, array t) { 31 | if (a.empty() || b.empty()) return {}; 32 | int N = 1 << (32 - __builtin_clz(max(sz(a), sz(b)) - 1)); 33 | static vector fa, fb; 34 | if (N > sz(fa)) fa.resize(N), fb.resize(N); 35 | 36 | copy(all(a), fa.begin()); 37 | fill(fa.begin() + sz(a), fa.begin() + N, 0); 38 | copy(all(b), fb.begin()); 39 | fill(fb.begin() + sz(b), fb.begin() + N, 0); 40 | 41 | transform(fa, N, t); 42 | transform(fb, N, t); 43 | for (int i = 0; i < N; i++) fa[i] = fa[i] * fb[i]; 44 | transform(fa, N, t); 45 | return { fa.begin(), fa.begin() + N }; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /graphs/chain_decomposition.cpp: -------------------------------------------------------------------------------- 1 | template struct chain_decomposition { 2 | const graph& g; 3 | 4 | vvi chains; 5 | vb artp, bridge; 6 | 7 | chain_decomposition(const graph& _g) : g(_g) { 8 | vi dfs_order, dfs_index(g.V, -1), parent_edge(g.V, -1); 9 | vector>> back_edges(g.V); 10 | 11 | vb seen_edge(g.EC, false); 12 | auto dfs = [&](auto& self, int u) -> void { 13 | dfs_index[u] = sz(dfs_order); 14 | dfs_order.pb(u); 15 | for (const E& e : g.edges[u]) if (!seen_edge[e.i]) { 16 | seen_edge[e.i] = true; 17 | if (dfs_index[e[u]] == -1) { 18 | parent_edge[e[u]] = e.i; 19 | self(self, e[u]); 20 | } else back_edges[e[u]].pb(e); 21 | } 22 | }; 23 | for (int u = 0; u < g.V; u++) if (dfs_index[u] == -1) dfs(dfs, u); 24 | 25 | artp.resize(g.V, false); 26 | bridge.resize(g.EC, true); 27 | 28 | vb visited(g.V, false); 29 | for (int u : dfs_order) for (const E& e : back_edges[u]) { 30 | chains.pb({e.i}); 31 | int v = e[u]; 32 | for (visited[u] = true; !visited[v]; ) { 33 | visited[v] = true; 34 | chains.back().pb(parent_edge[v]); 35 | v = g.edge_list[parent_edge[v]][v]; 36 | } 37 | for (int edge_index : chains.back()) bridge[edge_index] = false; 38 | if (sz(chains) > 1 && u == v) artp[u] = true; 39 | } 40 | 41 | for (const E& e : g.edge_list) if (bridge[e.i]) { 42 | if (sz(g.nbrs[e.u]) >= 2) artp[e.u] = true; 43 | if (sz(g.nbrs[e.v]) >= 2) artp[e.v] = true; 44 | } 45 | } 46 | 47 | bool is_articulation_point(int vertex) const { 48 | return artp[vertex]; 49 | } 50 | bool is_bridge(int edge_index) const { 51 | return bridge[edge_index]; 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /graphs/lca_jump_pointers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Supports O(logN) lowest common ancestor queries on an immutable tree. 3 | */ 4 | struct lowest_common_ancestor_log { 5 | int L, N; 6 | vi depth, link; 7 | 8 | lowest_common_ancestor_log() { } 9 | 10 | lowest_common_ancestor_log(const vvi &graph, int root = 0) : N(graph.size()) { 11 | L = 32 - __builtin_clz(N); 12 | depth.resize(N); 13 | link.resize(L*N); 14 | init(root, root, graph); 15 | } 16 | 17 | /* 18 | * Initializes the link table in O(NlogN). link[l * N + i] contains the index 19 | * of the (2 ** l)th ancestor of vertex i. 20 | */ 21 | void init(int loc, int par, const vvi &graph) { 22 | link[loc] = par; 23 | for (int l = 1; l < L; l++) 24 | link[l*N + loc] = link[(l-1)*N + link[(l-1)*N + loc]]; 25 | 26 | for (int nbr : graph[loc]) if (nbr != par) { 27 | depth[nbr] = depth[loc] + 1; 28 | init(nbr, loc, graph); 29 | } 30 | } 31 | 32 | // Returns the index of the dist-th ancestor of vertex loc in O(logN). 33 | int above(int loc, int dist) { 34 | dist = min(dist, N - 1); 35 | for (int l = 0; l < L; l++) 36 | if (dist & (1 << l)) 37 | loc = link[l*N + loc]; 38 | return loc; 39 | } 40 | 41 | // Returns the least common ancestor of vertices u and v in O(logN). 42 | int lca(int u, int v) { 43 | if (depth[u] > depth[v]) swap(u, v); 44 | v = above(v, depth[v] - depth[u]); 45 | if (u == v) return u; 46 | 47 | for (int l = L - 1; l >= 0; l--) { 48 | if (link[l*N + u] != link[l*N + v]) 49 | u = link[l*N + u], v = link[l*N + v]; 50 | } 51 | return link[u]; 52 | } 53 | 54 | int dist(int u, int v) { 55 | return depth[u] + depth[v] - 2 * depth[lca(u, v)]; 56 | } 57 | 58 | bool on_path(int u, int v, int inx) { 59 | return dist(u, v) == dist(u, inx) + dist(inx, v); 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /misc/count_distinct_in_range.cpp: -------------------------------------------------------------------------------- 1 | // {{{ data_structures/segment_tree_persistent.cpp }}} 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | template 9 | struct count_distinct_in_range { 10 | segment_tree_persistent> st; 11 | 12 | template 13 | count_distinct_in_range(InputIterator first, InputIterator last, int copies_allowed = 1) { 14 | assert(copies_allowed >= 1); 15 | 16 | std::vector> universe(first, last); 17 | std::sort(universe.begin(), universe.end()); 18 | universe.erase(std::unique(universe.begin(), universe.end()), universe.end()); 19 | 20 | std::vector> occurrences(universe.size()); 21 | 22 | int SZ = 0; 23 | for (InputIterator iter = first; iter != last; iter++) { 24 | int val = int(lower_bound(universe.begin(), universe.end(), *iter) - universe.begin()); 25 | occurrences[val].push_back(SZ); 26 | SZ++; 27 | } 28 | 29 | st = decltype(st)(SZ, 0, std::plus()); 30 | 31 | std::vector successor(SZ, -1); 32 | 33 | for (int i = 0; i < universe.size(); i++) { 34 | for (int j = 0; j < std::min(copies_allowed, int(occurrences[i].size())); j++) 35 | st.assign(occurrences[i][j], 1, -1); 36 | 37 | for (int j = 0; j + copies_allowed < int(occurrences[i].size()); j++) 38 | successor[occurrences[i][j]] = occurrences[i][j + copies_allowed]; 39 | } 40 | 41 | for (int i = 0; i < SZ; i++) 42 | if (successor[i] != -1) 43 | st.assign(successor[i], 1, i); 44 | } 45 | 46 | /* Returns the number of elements at indices in [first, last) counting only 47 | * the first 'copies_allowed' appearances of each distinct value. 48 | */ 49 | int get_count(int first, int last) { 50 | return st.accumulate(first, last, first); 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /data_structures/segment_tree_searchable.cpp: -------------------------------------------------------------------------------- 1 | // {{{ data_structures/segment_tree.cpp }}} 2 | 3 | #include 4 | 5 | template 6 | struct searchable_segment_tree : segment_tree { 7 | using segment_tree::SZ; 8 | using segment_tree::identity; 9 | using segment_tree::TT; 10 | using segment_tree::data; 11 | 12 | searchable_segment_tree() {} 13 | 14 | /* Rounds up internal size to the next power of 2 to enable binary search. 15 | */ 16 | searchable_segment_tree(int _SZ, T _identity, AssociativeOperation _TT) : 17 | segment_tree(1 << (32 - __builtin_clz(_SZ - 1)), _identity, _TT) {} 18 | 19 | /* Returns the smallest index "last" >= first such that p(accumulate(first, last)) 20 | * returns true. Returns SZ + 1 if no such index exists. Requires that 21 | * p(accumulate(first, last)) is non-decreasing as last increases. 22 | */ 23 | template 24 | int binary_search(int first, Predicate p) const { 25 | assert(0 <= first && first <= SZ); 26 | 27 | if (p(identity)) 28 | return first; 29 | 30 | first += SZ; 31 | 32 | T accumulator = identity; 33 | 34 | auto try_extend = [&](int bit) { 35 | assert(__builtin_ctz(first) >= bit); 36 | 37 | if (first + (1 << bit) > 2 * SZ) 38 | return false; 39 | 40 | T extended = TT(accumulator, data[first >> bit]); 41 | 42 | if (p(extended)) 43 | return false; 44 | 45 | accumulator = extended; 46 | first += 1 << bit; 47 | return true; 48 | }; 49 | 50 | int bit = 0; 51 | 52 | while (!(first & (1 << bit)) || try_extend(bit)) 53 | bit++; 54 | 55 | while (--bit >= 0) 56 | try_extend(bit); 57 | 58 | return first - SZ + 1; 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /data_structures/line_container_monotonic.cpp: -------------------------------------------------------------------------------- 1 | // {{{ data_structures/line }}} 2 | 3 | #include 4 | #include 5 | 6 | template 7 | struct line_container_monotonic : std::vector> { 8 | /* Inserts the line f(x) = a * x + b. 9 | * a must be non-decreasing across calls. 10 | */ 11 | void insert_line(T a, T b) { 12 | line ins = { a, b }; 13 | 14 | if (!this->empty()) { 15 | auto it = this->rbegin(); 16 | 17 | if (it->a > a) 18 | assert(false); 19 | 20 | if (it->a == a && it->b >= b) 21 | return; 22 | 23 | it->intersects_next = it->compute_intersection(ins); 24 | 25 | while (this->size() >= 2 && next(it)->intersects_next >= it->intersects_next) { 26 | this->pop_back(); 27 | it = next(it); 28 | it->intersects_next = it->compute_intersection(ins); 29 | } 30 | } 31 | 32 | this->push_back(ins); 33 | } 34 | 35 | /* Returns the maximum value at x among all inserted lines. 36 | */ 37 | T get_maximum(T x) const { 38 | assert(!this->empty()); 39 | return std::lower_bound(this->begin(), this->end(), x, [](const line &l, int _x) { 40 | return l.intersects_next < _x; 41 | })->evaluate(x); 42 | } 43 | 44 | /* Returns the maximum value at x among all inserted lines. 45 | * Total runtime complexity is linear over sequential calls made 46 | * with non-decreasing x if position is not modified externally. 47 | */ 48 | T get_maximum_monotonic(T x, size_t &position) const { 49 | assert(!this->empty()); 50 | 51 | if (position > this->size()) 52 | position = this->size(); 53 | 54 | while (position > 0 && (*this)[position - 1].intersects_next >= x) 55 | position--; 56 | 57 | while (x > (*this)[position].intersects_next) 58 | position++; 59 | 60 | return (*this)[position].evaluate(x); 61 | } 62 | }; 63 | -------------------------------------------------------------------------------- /test/data_structures/line_container/escape_through_leaf/escape_through_leaf.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://codeforces.com/problemset/problem/932/F 2 | 3 | #include 4 | using namespace std; 5 | 6 | // {{{ data_structures/line_container }}} 7 | 8 | // {{{ graphs/tree }}} 9 | 10 | template struct _reversed_struct { 11 | I &v_; 12 | explicit _reversed_struct(I &v) : v_{v} {} 13 | typename I::reverse_iterator begin() const { return v_.rbegin(); } 14 | typename I::reverse_iterator end() const { return v_.rend(); } 15 | }; 16 | template _reversed_struct reversed(I &v) { return _reversed_struct(v); } 17 | 18 | int main() { 19 | ios_base::sync_with_stdio(false); 20 | cin.tie(0); 21 | 22 | int N; 23 | cin >> N; 24 | 25 | vector a(N); 26 | for (int i = 0; i < N; i++) 27 | cin >> a[i]; 28 | 29 | vector b(N); 30 | for (int i = 0; i < N; i++) 31 | cin >> b[i]; 32 | 33 | tree tr(N, 0); 34 | re(tr, EDGE_LIST, 1); 35 | 36 | vector min_cost_path(N, 1e10); 37 | vector> leaf_paths(N); 38 | 39 | for (int u : reversed(tr.preorder)) { 40 | bool has_child = false; 41 | 42 | tr.for_each_child(u, [&](edge e) { 43 | has_child = true; 44 | 45 | int child = e.get_nbr(u); 46 | 47 | if (leaf_paths[child].size() > leaf_paths[u].size()) 48 | swap(leaf_paths[u], leaf_paths[child]); 49 | 50 | for (const line &l : leaf_paths[child]) 51 | leaf_paths[u].insert_line(l.a, l.b); 52 | 53 | leaf_paths[child].clear(); 54 | }); 55 | 56 | if (!has_child) 57 | min_cost_path[u] = 0; 58 | else 59 | min_cost_path[u] = -leaf_paths[u].get_maximum(a[u]); 60 | 61 | leaf_paths[u].insert_line(-b[u], -min_cost_path[u]); 62 | } 63 | 64 | for (int u = 0; u < N; u++) { 65 | if (u) cout << " "; 66 | cout << min_cost_path[u]; 67 | } 68 | cout << endl; 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /strings/palindromes.cpp: -------------------------------------------------------------------------------- 1 | // {{{ data_structures/sparse_table.cpp }}} 2 | 3 | #include 4 | #include 5 | 6 | struct palindromes { 7 | int SZ; 8 | std::vector width; 9 | 10 | template 11 | palindromes(I begin, I end) { 12 | SZ = int(end - begin); 13 | width.resize(std::max(2 * SZ - 1, 0)); 14 | 15 | auto match = [&](int c, int r) { 16 | if ((c - r) < -1 || (c + r) > int(width.size())) return false; 17 | return (c - r)&1 || *(begin + (c - r)/2) == *(begin + (c + r)/2); 18 | }; 19 | 20 | for (int cen = 0, lim = -1, ref; cen < int(width.size()); cen++) { 21 | if (lim > cen) 22 | width[cen] = std::min(width[2 * ref - cen], lim - cen); 23 | while (match(cen, width[cen] + 1)) 24 | width[cen]++; 25 | if (cen + width[cen] > lim) { 26 | lim = cen + width[cen]; 27 | ref = cen; 28 | } 29 | } 30 | } 31 | 32 | int longest_centered_at(int index) const { 33 | assert(0 <= index && index < SZ); 34 | return width[2 * index]; 35 | } 36 | 37 | int longest_centered_right_of(int index) const { 38 | assert(0 <= index && index < SZ - 1); 39 | return width[2 * index + 1]; 40 | } 41 | 42 | int longest_within_substring(int pos, int len) const { 43 | static sparse_table 44 | width_rmq(int(width.size()), std::max, [&](int i) { return width[i]; }); 45 | 46 | assert(0 <= pos && pos + len <= SZ); 47 | 48 | int lo = 0, hi = len + 1; 49 | while (hi - lo > 1) { 50 | int mi = lo + (hi - lo) / 2; 51 | int min_c = std::min(2 * (pos + mi / 2), 2 * (pos + (mi - 2 + 1) / 2) + 1); 52 | int max_c = std::max(2 * (pos + len - mi / 2) - 1, 2 * (pos + len - (mi + 1) / 2)); 53 | if (min_c < max_c && width_rmq.accumulate(min_c, max_c) >= mi) 54 | lo = mi; 55 | else 56 | hi = mi; 57 | } 58 | return lo; 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /strings/knuth_morris_pratt.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct knuth_morris_pratt { 4 | int SZ; 5 | std::vector pattern; 6 | std::vector suffix_link; 7 | 8 | int append(int matched, int c) const { 9 | while (matched > 0 && pattern[matched] != c) 10 | matched = suffix_link[matched]; 11 | return matched + int(pattern[matched] == c); 12 | } 13 | 14 | knuth_morris_pratt() : SZ(0) { } 15 | 16 | template 17 | knuth_morris_pratt(InputIterator begin, InputIterator end) { 18 | initialize(begin, end); 19 | } 20 | 21 | template 22 | void initialize(InputIterator begin, InputIterator end) { 23 | pattern.resize(end - begin); 24 | copy(begin, end, pattern.begin()); 25 | 26 | SZ = int(pattern.size()); 27 | suffix_link.resize(SZ + 1); 28 | 29 | for (int matched = 1; matched < SZ; matched++) 30 | suffix_link[matched + 1] = append(suffix_link[matched], pattern[matched]); 31 | } 32 | 33 | template 34 | void find_matches(InputIterator begin, InputIterator end, F consume) const { 35 | int i = 0; 36 | int matched = 0; 37 | for (InputIterator iter = begin; iter != end; iter++, i++) { 38 | matched = append(matched, *iter); 39 | if (matched == SZ) { 40 | consume(i - SZ + 1); 41 | matched = suffix_link[matched]; 42 | } 43 | } 44 | } 45 | 46 | template 47 | int count_matches(InputIterator begin, InputIterator end) const { 48 | int count = 0; 49 | find_matches(begin, end, [&](__attribute((unused))int index) { count++; }); 50 | return count; 51 | } 52 | 53 | template 54 | std::vector indices_of_matches(InputIterator begin, InputIterator end) const { 55 | std::vector indices; 56 | find_matches(begin, end, [&](int index) { indices.push_back(index); }); 57 | return indices; 58 | } 59 | }; 60 | -------------------------------------------------------------------------------- /.circleci/expand_dependencies.py: -------------------------------------------------------------------------------- 1 | import re 2 | import os 3 | import sys 4 | 5 | from util import canonical_path 6 | 7 | def expand(infile, outfile, clib_root = "~/clib/"): 8 | deps = {} 9 | file_contents = {} 10 | unique_files = [ infile ] 11 | 12 | dependency_re = re.compile("//\s*{{{(.*)}}}\s*") 13 | 14 | inx = 0 15 | while inx < len(unique_files): 16 | fpath = unique_files[inx] 17 | inx += 1 18 | 19 | with open(fpath) as f: 20 | lines = f.readlines() 21 | 22 | deps[fpath] = [] 23 | file_contents[fpath] = lines 24 | 25 | for line in lines: 26 | match = dependency_re.match(line) 27 | if match: 28 | dep_fpath = canonical_path(clib_root + match.group(1).strip()) 29 | deps[fpath].append(dep_fpath) 30 | if dep_fpath not in unique_files: 31 | unique_files.append(dep_fpath) 32 | 33 | write_order = [] 34 | 35 | while len(write_order) < len(unique_files): 36 | appended = False 37 | 38 | for fpath in unique_files: 39 | if fpath in write_order: 40 | continue 41 | 42 | can_write = True 43 | for dep in deps[fpath]: 44 | if dep not in write_order: 45 | can_write = False 46 | 47 | if can_write: 48 | write_order.append(fpath) 49 | appended = True 50 | 51 | if not appended: 52 | print("Encountered a cyclic dependency!") 53 | exit(1) 54 | 55 | with open(outfile, 'w') as outf: 56 | for fpath in write_order: 57 | outf.writelines(file_contents[fpath]) 58 | outf.write("\n") 59 | 60 | if __name__ == "__main__": 61 | if len(sys.argv) < 2: 62 | print("Path to source file expected as argument") 63 | exit(1) 64 | 65 | if len(sys.argv) < 3: 66 | print("Output filepath expected as argument") 67 | exit(1) 68 | 69 | clib_root = "~/clib/" 70 | if len(sys.argv) >= 4: 71 | clib_root = sys.argv[3] 72 | 73 | expand(sys.argv[1], sys.argv[2], clib_root) 74 | 75 | -------------------------------------------------------------------------------- /numeric/discrete_logarithm.cpp: -------------------------------------------------------------------------------- 1 | // {{{ data_structures/splitmix64_hash_map.cpp }}} 2 | 3 | #include 4 | #include 5 | 6 | int product(int x, int y, int MOD) { 7 | return int(int64_t(x) * y % MOD); 8 | } 9 | 10 | int mod_pow(int x, int k, int MOD) { 11 | if (!k) return 1; 12 | if (k&1) return product(x, mod_pow(x, k - 1, MOD), MOD); 13 | return mod_pow(product(x, x, MOD), k / 2, MOD); 14 | } 15 | 16 | int totient(int v) { 17 | int tot = v; 18 | for (int p = 2; p * p <= v; p++) if (v % p == 0) { 19 | tot = tot / p * (p - 1); 20 | while (v % p == 0) v /= p; 21 | } 22 | if (v > 1) tot = tot / v * (v - 1); 23 | return tot; 24 | } 25 | 26 | /* Returns the smallest K >= 0 such that init * pow(x, K) === y modulo MOD. 27 | * Returns -1 if no such K exists. Runs in O(sqrt(MOD)). 28 | */ 29 | int discrete_log(int x, int y, int MOD, int init = 1) { 30 | if (x == 0) 31 | return y == 1 ? 0 : y == 0 ? MOD > 1 : -1; 32 | 33 | int prefix = 0; 34 | while (init != y && std::gcd(init, MOD) != std::gcd(product(init, x, MOD), MOD)) { 35 | init = product(init, x, MOD); 36 | prefix++; 37 | } 38 | 39 | if (init == y) 40 | return prefix; 41 | 42 | if (std::gcd(init, MOD) != std::gcd(y, MOD)) 43 | return -1; 44 | 45 | MOD = MOD / std::gcd(init, MOD); 46 | 47 | x %= MOD; 48 | y %= MOD; 49 | init %= MOD; 50 | 51 | int subgroup_order = totient(MOD); 52 | 53 | y = product(y, mod_pow(init, subgroup_order - 1, MOD), MOD); 54 | 55 | int step_size = 0; 56 | while (step_size * step_size < subgroup_order) 57 | step_size++; 58 | 59 | umap table; 60 | 61 | int baby_step = 1; 62 | for (int i = 0; i < step_size; i++) { 63 | table[baby_step] = i; 64 | baby_step = product(baby_step, x, MOD); 65 | } 66 | 67 | int giant_step = mod_pow(x, subgroup_order - step_size, MOD); 68 | for (int i = 0; i < step_size; i++) { 69 | auto it = table.find(y); 70 | if (it != table.end()) 71 | return prefix + i * step_size + it->second; 72 | y = product(y, giant_step, MOD); 73 | } 74 | 75 | return -1; 76 | } 77 | -------------------------------------------------------------------------------- /graphs/lowest_common_ancestor.cpp: -------------------------------------------------------------------------------- 1 | // {{{ graphs/tree.cpp }}} 2 | // {{{ data_structures/sparse_table.cpp }}} 3 | 4 | #include 5 | 6 | template 7 | struct lowest_common_ancestor { 8 | const tree& t; 9 | 10 | std::vector euler_tour, tour_depths, first_visit, last_visit; 11 | 12 | int operator()(int i, int j) const { 13 | // if two visits have equal depth we prefer the later, allowing us to compute first_step 14 | return tour_depths[i] < tour_depths[j] ? i : j; 15 | } 16 | 17 | sparse_table&> tour_table; 18 | 19 | lowest_common_ancestor() {} 20 | 21 | lowest_common_ancestor(const tree& _t) : t(_t), first_visit(t.V), last_visit(t.V), tour_table(*this) { 22 | record_tour(t.root); 23 | tour_table.construct(int(euler_tour.size()), [](int i) { return i; }); 24 | } 25 | 26 | void record_tour(int u) { 27 | first_visit[u] = int(euler_tour.size()); 28 | euler_tour.push_back(u); 29 | tour_depths.push_back(t.depth[u]); 30 | 31 | t.for_each_child(u, [&](const Edge& e) { 32 | record_tour(e.get_nbr(u)); 33 | euler_tour.push_back(u); 34 | tour_depths.push_back(t.depth[u]); 35 | }); 36 | 37 | last_visit[u] = int(euler_tour.size()) - 1; 38 | } 39 | 40 | int lca(int u, int v) const { 41 | u = first_visit[u], v = first_visit[v]; 42 | if (u > v) std::swap(u, v); 43 | return euler_tour[tour_table.accumulate(u, v + 1)]; 44 | } 45 | 46 | int dist(int u, int v) const { 47 | return t.depth[u] + t.depth[v] - 2 * t.depth[lca(u, v)]; 48 | } 49 | 50 | bool uv_path_has_w(int u, int v, int w) const { 51 | return w != -1 && dist(u, v) == (dist(u, w) + dist(w, v)); 52 | } 53 | 54 | bool is_ancestor(int anc, int desc) const { 55 | return first_visit[anc] <= first_visit[desc] && first_visit[desc] <= last_visit[anc]; 56 | } 57 | 58 | // Returns the neighbor of u on the simple path from u to v 59 | int first_step(int u, int v) const { 60 | assert(u != v); 61 | if (!is_ancestor(u, v)) return t.parent[u]; 62 | return euler_tour[tour_table.accumulate(first_visit[u], first_visit[v]) + 1]; 63 | } 64 | }; 65 | -------------------------------------------------------------------------------- /graphs/condensed_tree.cpp: -------------------------------------------------------------------------------- 1 | template struct condensed_tree { 2 | const lowest_common_ancestor& t; 3 | vi label, above; vb interesting; int root, L; 4 | 5 | condensed_tree(const lowest_common_ancestor& _t, vi points_of_interest, 6 | int _root = -1) : t(_t), label(_t.t.V, -1), interesting(_t.t.V, 0), root(_root), L(0) { 7 | sort(all(points_of_interest), [&](const int &a, const int &b) { return t.first_visit[a] < t.first_visit[b]; }); 8 | unique(all(points_of_interest)); 9 | for (int i = 0; i < sz(points_of_interest); i++) { 10 | interesting[points_of_interest[i]] = true; 11 | if (i) interesting[t.lca(points_of_interest[i-1], points_of_interest[i])] = true; 12 | } 13 | if (root != -1) interesting[root] = true; 14 | 15 | for (int u : t.preorder) if (interesting[u]) { 16 | label[u] = L; 17 | int v = t.par(u); 18 | if (v == -1 || interesting[v]) { 19 | above.pb(v != -1 ? label[v] : -1), L++; 20 | continue; 21 | } 22 | if (root == -1) above.pb(++L); 23 | for (; v != -1 && !interesting[v]; v = t.par(v)) 24 | label[v] = L; 25 | above.pb(v != -1 ? label[v] : -1), L++; 26 | } 27 | } 28 | 29 | const vi& decompose_path(int u, int v, bool include_lca) const { 30 | static vi res; res.clear(); 31 | int w = t.lca(u, v); if (root != -1) assert(root == w); 32 | assert(interesting[u] && interesting[v] && interesting[w]); 33 | for (int x = label[u]; x != label[w]; x = above[x]) res.pb(x); 34 | if (include_lca) res.pb(label[w]); 35 | size_t bef = res.size(); 36 | for (int x = label[v]; x != label[w]; x = above[x]) res.pb(x); 37 | reverse(res.begin() + bef, res.end()); 38 | return res; 39 | } 40 | 41 | template 42 | void for_each_label_commutative(int u, int v, bool include_lca, F f) const { 43 | int w = t.lca(u, v); if (root != -1) assert(root == w); 44 | assert(interesting[u] && interesting[v] && interesting[w]); 45 | for (int x = label[u]; x != label[w]; x = above[x]) f(x); 46 | if (include_lca) f(label[w]); 47 | for (int x = label[v]; x != label[w]; x = above[x]) f(x); 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /graphs/dinic.cpp: -------------------------------------------------------------------------------- 1 | template struct dinic { 2 | static const F inf = numeric_limits::max(); 3 | 4 | int V; 5 | vvi adj; 6 | vi dest; 7 | vector cap; 8 | 9 | dinic (int V = 0) : V(V) { 10 | adj.resize(V); 11 | } 12 | 13 | void __arc(int u, int v, F c) { 14 | adj[u].push_back(dest.size()); 15 | dest.push_back(v); 16 | cap.push_back(c); 17 | } 18 | 19 | // Inserts a directed edge u --> v with capacity c. 20 | int arc(int u, int v, F c) { 21 | __arc(u, v, c); 22 | __arc(v, u, F(0)); 23 | return sz(dest) - 2; 24 | } 25 | 26 | mutable vi level; 27 | void bfs(int s, vector& flow) const { 28 | level.resz(V), fill(all(level), -1), level[s] = 0; 29 | for (queue q({s}); !q.empty(); q.pop()) { 30 | for (int e : adj[q.front()]) { 31 | if (level[dest[e]] == -1 && flow[e] < cap[e]) { 32 | level[dest[e]] = level[q.front()] + 1; 33 | q.push(dest[e]); 34 | } 35 | } 36 | } 37 | } 38 | 39 | mutable vi inx; 40 | F augment(int s, int t, vector& flow, F cur = inf) const { 41 | if (s == t) return cur; 42 | for (; inx[s] < adj[s].size(); inx[s]++) { 43 | int e = adj[s][inx[s]]; 44 | if (level[dest[e]] != level[s] + 1) continue; 45 | if (flow[e] == cap[e]) continue; 46 | if (F incr = augment(dest[e], t, flow, min(cur, cap[e] - flow[e]))) { 47 | flow[e] += incr; 48 | flow[e^1] -= incr; 49 | return incr; 50 | } 51 | } 52 | return 0; 53 | } 54 | 55 | /* 56 | * Computes a maximum flow from node s to node t. 57 | * 58 | * Runs in O(V^2 * E) in the general case. 59 | * Runs in O(min{ V^(2/3), E^(1/2) } * E) if all edges have unit capacity. 60 | * Runs in O(V^(1/2) * E) for bipartite matching. 61 | */ 62 | struct max_flow { 63 | F res; 64 | vector flow; 65 | }; 66 | max_flow solve(int s, int t) const { 67 | assert(s != t); 68 | F res = 0; 69 | vector flow(cap.size()); 70 | while (bfs(s, flow), ~level[t]) { 71 | inx.resz(V), fill(all(inx), 0); 72 | while (F incr = augment(s, t, flow)) 73 | res += incr; 74 | } 75 | return max_flow{res, flow}; 76 | } 77 | }; 78 | -------------------------------------------------------------------------------- /numeric/karatsuba.cpp: -------------------------------------------------------------------------------- 1 | // Naive O(AB) multiplication of polynomials a and b 2 | template 3 | T* naive_product(T* c, const T* ai, const T* aj, const T* bi, const T* bj) { 4 | T* ce = c + (aj - ai) + (bj - bi) - 1; 5 | fill(c, ce, T{}); 6 | for (auto a = ai; a < aj; a++) 7 | for (auto b = bi; b < bj; b++) 8 | c[a - ai + b - bi] += *a * *b; 9 | return ce; 10 | } 11 | 12 | template 13 | vector naive_product(const vector& a, const vector& b) { 14 | vector c(sz(a) + sz(b) - 1); 15 | naive_product(c.data(), a.data(), a.data() + sz(a), b.data(), b.data() + sz(b)); 16 | return c; 17 | } 18 | 19 | template T get(T* i, T* j, int k) { 20 | return i + k < j ? *(i + k) : T{}; 21 | } 22 | 23 | // O(max(A, B)^log_2(3)) multiplication of polynomials a and b 24 | template 25 | T* karatsuba(T* c, const T* ai, const T* aj, const T* bi, const T* bj) { 26 | if (ai >= aj || bi >= bj) return c; 27 | if (aj - ai < SZ) return naive_product(c, ai, aj, bi, bj); 28 | assert(aj - ai >= bj - bi); 29 | 30 | const int N = aj - ai + bj - bi - 1; 31 | const int M = (aj - ai + 1) / 2; 32 | const int S = max(N, 3 * M); 33 | 34 | for (int i = 0; i < M; i++) { 35 | c[0 + i] = get(ai, aj, i) + get(ai, aj, M + i); 36 | c[5 * M + i] = get(bi, bj, i) + get(bi, bj, M + i); 37 | } 38 | karatsuba(c + M, c, c + M, c + 5 * M, c + 6 * M); 39 | c[3 * M - 1] = T{}; 40 | 41 | T* ce = karatsuba(c + S, ai, ai + M, bi, min(bi + M, bj)); 42 | for (int i = 0; i < N; i++) { 43 | if (i < M) c[i] = get(c + S, ce, i); 44 | else if (i < 2 * M) c[i] += get(c + S, ce, i) - get(c + S, ce, i - M); 45 | else c[i] -= get(c + S, ce, i - M); 46 | } 47 | 48 | ce = karatsuba(c + S, ai + M, aj, bi + M, bj); 49 | for (int i = M; i < N; i++) { 50 | if (i < 2 * M) c[i] -= get(c + S, ce, i - M); 51 | else if (i < 3 * M) c[i] += get(c + S, ce, i - 2 * M) - get(c + S, ce, i - M); 52 | else c[i] = get(c + S, ce, i - 2 * M); 53 | } 54 | 55 | return c + N; 56 | } 57 | 58 | template 59 | vector karatsuba(const vector& _a, const vector& _b) { 60 | auto& a = sz(_a) > sz(_b) ? _a : _b, b = sz(_a) > sz(_b) ? _b : _a; 61 | if (sz(a) < SZ) return naive_product(a, b); 62 | vector c(4 * (sz(a) + 1)); 63 | karatsuba(c.data(), a.data(), a.data() + sz(a), b.data(), b.data() + sz(b)); 64 | c.erase(c.begin() + sz(a) + sz(b) - 1, c.end()); 65 | return c; 66 | } 67 | -------------------------------------------------------------------------------- /graphs/two_sat.cpp: -------------------------------------------------------------------------------- 1 | // {{{ graphs/strongly_connected_components.cpp }}} 2 | // {{{ graphs/digraph_reachability.cpp }}} 3 | 4 | #include 5 | #include 6 | 7 | struct two_sat { 8 | std::vector> graph; 9 | 10 | two_sat(int SZ) : graph(2 * SZ) {} 11 | 12 | int new_var() { 13 | graph.push_back({}); 14 | graph.push_back({}); 15 | return int(graph.size()) - 1; 16 | } 17 | 18 | static inline int neg(int a) { return a^1; } 19 | 20 | void implies(int a, int b) { 21 | if (a < 0 || b < 0) return; 22 | graph[a].push_back(b); 23 | graph[neg(b)].push_back(neg(a)); 24 | } 25 | 26 | void assign(int a, int v) { 27 | if (v) implies(neg(a), a); 28 | else implies(a, neg(a)); 29 | } 30 | void constrain_equal(int a, int b) { 31 | implies(a, b); 32 | implies(neg(a), neg(b)); 33 | } 34 | void constrain_not_equal(int a, int b) { 35 | implies(a, neg(b)); 36 | implies(neg(a), b); 37 | } 38 | void constrain_at_most_one(int a, int b) { 39 | implies(a, neg(b)); // contrapositive is automatic 40 | } 41 | void constraint_at_least_one(int a, int b) { 42 | implies(neg(a), b); // contrapositive is automatic 43 | } 44 | 45 | int make_or(int a, int b) { 46 | if (a < 0) return b; 47 | if (b < 0) return a; 48 | int v = new_var(); 49 | implies(a, v); 50 | implies(b, v); 51 | return v; 52 | } 53 | 54 | int make_and(int a, int b) { 55 | if (a < 0) return b; 56 | if (b < 0) return a; 57 | int v = new_var(); 58 | implies(v, a); 59 | implies(v, b); 60 | return v; 61 | } 62 | 63 | std::vector solve() const { 64 | scc s = strongly_connected_components(graph); 65 | std::vector assignment(int(graph.size()) / 2); 66 | 67 | for (int v = 0; v < int(graph.size()); v += 2) { 68 | if (s.label[v] == s.label[v + 1]) 69 | return {}; 70 | 71 | assignment[v / 2] = s.label[v] > s.label[v + 1]; 72 | } 73 | return assignment; 74 | } 75 | 76 | // (2 * MAXV)^2 / machine word size 77 | template 78 | std::string classify() const { 79 | auto reach = digraph_reachability<2 * MAXV>(graph); 80 | std::string res(int(graph.size()), '?'); 81 | for (int v = 0; v < int(graph.size()); v++) { 82 | bool n0 = reach[v][neg(v)]; 83 | bool n1 = reach[neg(v)][v]; 84 | if (n0 && n1) return ""; 85 | res[v] = n0 ? '0' : n1 ? '1' : '?'; 86 | } 87 | return res; 88 | } 89 | }; 90 | -------------------------------------------------------------------------------- /graphs/tree_isomorphism.cpp: -------------------------------------------------------------------------------- 1 | void collect_by_depth(vvi& d, int u, bool avoid_erased, int p = -1, int d0 = 0) const { 2 | if (d0 >= sz(d)) d.resize(d0 + 1); 3 | d[d0].push_back(u); 4 | for (int v : nbrs[u]) if (v != p && (!avoid_erased || !erased[v])) { 5 | collect_by_depth(d, v, avoid_erased, u, d0+1); 6 | } 7 | } 8 | 9 | friend bool rooted_iso(const tree& a, int ra, 10 | const tree& b, int rb, bool avoid_erased = 1) { 11 | vvi abd, bbd; 12 | a.collect_by_depth(abd, ra, avoid_erased); 13 | b.collect_by_depth(bbd, rb, avoid_erased); 14 | if (sz(abd) != sz(bbd)) return false; 15 | 16 | int D = sz(abd); 17 | vi alb, blb; 18 | for (int d = D - 1; d >= 0; d--) { 19 | vi &al = abd[d], &bl = bbd[d]; 20 | sort(all(al)), sort(all(bl)); 21 | int L = sz(al); if (L != sz(bl)) return false; 22 | 23 | vector> ac(L), bc(L); 24 | if (d + 1 < D) { 25 | const vi &na = abd[d+1], &nb = bbd[d+1]; 26 | for (int i = 0; i < L; i++) { 27 | ac[i].s = bc[i].s = i; 28 | for (int n : a.nbrs[al[i]]) { 29 | auto it = lb(all(na), n); 30 | if (it != na.end() && *it == n) 31 | ac[i].f.pb(alb[it - na.begin()]); 32 | } 33 | for (int n : b.nbrs[bl[i]]) { 34 | auto it = lb(all(nb), n); 35 | if (it != nb.end() && *it == n) 36 | bc[i].f.pb(blb[it - nb.begin()]); 37 | } 38 | sort(all(ac[i].f)), sort(all(bc[i].f)); 39 | } 40 | } 41 | sort(all(ac)), sort(all(bc)); 42 | 43 | alb.resize(sz(ac)), blb.resize(sz(bc)); 44 | if (d + 1 < D) for (int i = 0, j = 0; i < sz(ac); i++) { 45 | if (ac[i].f != bc[i].f) return false; 46 | if (i && (ac[i].f != ac[i-1].f)) j++; 47 | alb[ac[i].s] = blb[bc[i].s] = j; 48 | } 49 | } 50 | 51 | return true; 52 | } 53 | 54 | friend bool iso(const tree& a, int ra, 55 | const tree& b, int rb, bool avoid_erased = 1) { 56 | int ca = a.centroids(ra, avoid_erased)[0]; 57 | for (int cb : b.centroids(rb, avoid_erased)) 58 | if (rooted_iso(a, ca, b, cb, avoid_erased)) 59 | return true; 60 | return false; 61 | } 62 | friend bool iso(const tree& a, const tree& b) { 63 | return iso(a, 0, b, 0, 0); 64 | } 65 | -------------------------------------------------------------------------------- /graphs/centroid_decomposition.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct centroid_decomposition { 3 | static const int L = 33 - __builtin_clz(MAXV - 1); 4 | 5 | const tree& t; 6 | using P = typename E::path; 7 | struct visit { int node; E in; }; 8 | vi layer; // 0-indexed depth in the centroid tree 9 | vpii par; // {parent, index among parent's children} 10 | vi child_ct; // number of children 11 | vector> anc_path; // paths to ancestors, by layer 12 | vector> preorder; // preorder traversals recording {node, incoming edge} 13 | vvi ch_sz; // child tree sizes in traversal order 14 | 15 | centroid_decomposition(const tree& _t) : t(_t), 16 | layer(t.V, -1), par(t.V), child_ct(t.V), anc_path(t.V) { 17 | assert(t.V <= MAXV); 18 | if (PREORDER) preorder.resz(t.V), ch_sz.resz(t.V); 19 | subt_sz = t.subt_sz, decompose(t.root), subt_sz.clear(); 20 | } 21 | 22 | vi subt_sz; 23 | int centroid(int r) { 24 | int c = r; 25 | FIND: for (E e : t.nbrs[c]) if (int u = e(c); layer[u] == -1) { 26 | if (subt_sz[u] < subt_sz[c] && 2 * subt_sz[u] >= subt_sz[r]) { 27 | c = u; goto FIND; 28 | } 29 | } 30 | return c; 31 | } 32 | 33 | int ly = 0, rt = 0; 34 | void traverse(int u, E in) { 35 | if (PREORDER) preorder[rt].pb({u, in}); 36 | subt_sz[u] = 1; 37 | for (E e : t.nbrs[u]) if (int v = e(u); v != in(u) && layer[v] == -1) { 38 | anc_path[v][ly] = anc_path[u][ly] + P(e); 39 | traverse(v, e); 40 | subt_sz[u] += subt_sz[v]; 41 | } 42 | } 43 | 44 | void decompose(int r = 0, int p = -1, int i = 0) { 45 | par[r = centroid(r)] = {p, i}, i = 0; 46 | layer[r] = ly; 47 | if (PREORDER) preorder[r] = {{r, E()}}; 48 | subt_sz[r] = 1; 49 | for (E e : t.nbrs[r]) if (int u = e(r); layer[u] == -1) { 50 | if (PREORDER) ch_sz[r].pb(-sz(preorder[r])); 51 | rt = r, anc_path[u][ly] = P(e), traverse(u, e); 52 | if (PREORDER) ch_sz[r].back() += sz(preorder[r]); 53 | subt_sz[r] += subt_sz[u], child_ct[r]++; 54 | ly++, decompose(u, r, i++), ly--; 55 | } 56 | } 57 | 58 | int lca(int u, int v) const { 59 | if (layer[u] < layer[v]) swap(u, v); 60 | while (layer[u] != layer[v]) u = par[u].f; 61 | while (u != v) u = par[u].f, v = par[v].f; 62 | return u; 63 | } 64 | 65 | P dist(int u, int v) const { 66 | int clca = lca(u, v); 67 | return anc_path[u][layer[clca]] + anc_path[v][layer[clca]]; 68 | } 69 | }; 70 | -------------------------------------------------------------------------------- /numeric/sieve.cpp: -------------------------------------------------------------------------------- 1 | enum DIVISOR_TYPE { ALL, SQUARE_FREE }; 2 | template struct sieve { 3 | vi primes; 4 | struct num { 5 | int least_prime; // least prime divisor 6 | int div_least_prime; // num divided by least_prime 7 | char lp_multiplicity; // multiplicity of the least prime divisor 8 | char mu; // mobius function 9 | int phi; // euler's totient function 10 | 11 | static num ONE() { return { INT_MAX, 1, 0, 1, 1}; } 12 | 13 | num prod(int my_value, int p) const { 14 | if (p < least_prime) 15 | return { p, my_value, 1, char(-mu), phi * (p - 1) }; 16 | assert(p == least_prime); 17 | return { p, my_value, char(lp_multiplicity + 1), 0, phi * p }; 18 | } 19 | }; 20 | vector nums; 21 | const num& operator[](int i){ return nums[i]; } 22 | 23 | sieve() : nums(MAXV) { 24 | nums[1] = num::ONE(); 25 | for (int v = 2; v < MAXV; v++) { 26 | num& n = nums[v]; 27 | if (!n.least_prime) { 28 | n = nums[1].prod(1, v); 29 | primes.pb(v); 30 | } 31 | for (int p : primes) { 32 | if (p > n.least_prime || v * p >= MAXV) break; 33 | nums[v * p] = n.prod(v, p); 34 | } 35 | } 36 | } 37 | 38 | bool is_prime(int v) const { 39 | assert(0 < v && v < MAXV); 40 | return nums[v].least_prime == v; 41 | } 42 | 43 | int eliminate_least_prime(int v) const { 44 | assert(1 < v && v < MAXV); 45 | for (int m = nums[v].lp_multiplicity; m > 0; m--) 46 | v = nums[v].div_least_prime; 47 | return v; 48 | } 49 | 50 | const vpii& factor(int v) const { 51 | assert(0 < v && v < MAXV); 52 | static vpii res; res.clear(); 53 | for (; v > 1; v = eliminate_least_prime(v)) 54 | res.emplace_back(nums[v].least_prime, nums[v].lp_multiplicity); 55 | reverse(all(res)); 56 | return res; 57 | } 58 | 59 | template void for_each_divisor_unordered(int v, F f, 60 | DIVISOR_TYPE t = ALL, int d = 1) const { 61 | assert(0 < v && v < MAXV); 62 | if (v == 1) { f(d); return; } 63 | int w = eliminate_least_prime(v); 64 | char M = min(nums[v].lp_multiplicity, char(t == ALL ? CHAR_MAX : 1)); 65 | for (int m = 0; m <= M; m++, d *= nums[v].least_prime) { 66 | for_each_divisor_unordered(w, f, t, d); 67 | } 68 | } 69 | 70 | const vi& unordered_divisors(int v, DIVISOR_TYPE t = ALL) const { 71 | assert(0 < v && v < MAXV); 72 | static vi res; res.clear(); 73 | for_each_divisor_unordered(v, [&](int d) { res.pb(d); }, t); 74 | return res; 75 | } 76 | }; 77 | -------------------------------------------------------------------------------- /strings/mutable_string.cpp: -------------------------------------------------------------------------------- 1 | // {{{ strings/suffix_automaton.cpp }}} 2 | // {{{ strings/knuth_morris_pratt.cpp }}} 3 | 4 | #include 5 | #include 6 | 7 | template 8 | struct mutable_string { 9 | int SZ; 10 | std::vector data; 11 | 12 | int BLOCK_SZ; 13 | std::vector> blocks; 14 | 15 | template 16 | mutable_string(InputIterator begin, InputIterator end) : data(begin, end) { 17 | SZ = int(data.size()); 18 | BLOCK_SZ = int(ceil(std::sqrt(data.size()))); 19 | for (int i = 0; i < SZ; i += BLOCK_SZ) 20 | blocks.emplace_back(data.begin() + i, data.begin() + std::min(i + BLOCK_SZ, SZ)); 21 | } 22 | 23 | std::vector::iterator block_start(int block_id) { 24 | return data.begin() + std::min(block_id * BLOCK_SZ, SZ); 25 | } 26 | std::vector::const_iterator block_start(int block_id) const { 27 | return data.begin() + std::min(block_id * BLOCK_SZ, SZ); 28 | } 29 | 30 | // O(sqrt(SZ)) 31 | void assign(int i, int c) { 32 | data[i] = c; 33 | int block_id = i / BLOCK_SZ; 34 | blocks[block_id].initialize(block_start(block_id), block_start(block_id + 1)); 35 | } 36 | 37 | // O(min(|end - begin| * sqrt(SZ), |end - begin| + len)) 38 | template 39 | int count_matches_in_substring(InputIterator begin, InputIterator end, int L, int R) const { 40 | static knuth_morris_pratt kmp; 41 | kmp.initialize(begin, end); 42 | 43 | int first_block_id = (L + BLOCK_SZ - 1) / BLOCK_SZ; 44 | int last_block_id = R / BLOCK_SZ; 45 | 46 | int expected_work = 47 | first_block_id * BLOCK_SZ - L 48 | + (last_block_id - first_block_id) * 3 * kmp.SZ 49 | + R - last_block_id * BLOCK_SZ; 50 | 51 | if (first_block_id >= last_block_id || kmp.SZ > BLOCK_SZ || expected_work >= R - L) 52 | return kmp.count_matches(data.begin() + L, data.begin() + R); 53 | 54 | int count = 0; 55 | 56 | count += kmp.count_matches(data.begin() + L, block_start(first_block_id) + kmp.SZ - 1); 57 | 58 | for (int block_id = first_block_id; block_id < last_block_id; block_id++) { 59 | count += blocks[block_id].count_occurrences(begin, end); 60 | 61 | if (block_id != first_block_id) { 62 | auto boundary = block_start(block_id); 63 | count += kmp.count_matches(boundary - kmp.SZ + 1, boundary + kmp.SZ - 1); 64 | } 65 | } 66 | 67 | count += kmp.count_matches(block_start(last_block_id) - kmp.SZ + 1, data.begin() + R); 68 | 69 | return count; 70 | } 71 | 72 | template 73 | int count_matches(InputIterator begin, InputIterator end) const { 74 | return count_matches_in_substring(begin, end, 0, SZ); 75 | } 76 | }; 77 | -------------------------------------------------------------------------------- /data_structures/binary_indexed_tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | template 7 | struct binary_indexed_tree { 8 | int SZ; 9 | T identity; 10 | AssociativeOperation TT; 11 | InverseOperation S; 12 | std::vector data; 13 | 14 | binary_indexed_tree() {} 15 | 16 | binary_indexed_tree(int _SZ, T _identity, AssociativeOperation _TT, InverseOperation _S = nullptr) 17 | : SZ(_SZ), identity(_identity), TT(_TT), S(_S) { 18 | data.assign(2 * SZ, identity); 19 | } 20 | 21 | // Replaces the current value at index i with TT(current value, v) 22 | void add(int i, T v) { 23 | for (i++; i <= SZ; i += i & -i) 24 | data[i] = TT(data[i], v); 25 | } 26 | 27 | // Replaces the element at index i with v. Requires InverseOperation to be defined. 28 | void replace(int i, T v) { 29 | static_assert(!std::is_same::value, "InverseOperation not defined."); 30 | add(i, S(v, get(i))); 31 | } 32 | 33 | // Returns the value at index i. Requires InverseOperation to be defined. 34 | T get(int i) const { 35 | static_assert(!std::is_same::value, "InverseOperation not defined."); 36 | return accumulate(i, i + 1); 37 | } 38 | 39 | // Returns the result of accumulating the elements at indices in [0, len) 40 | T accumulate_prefix(int len) const { 41 | assert(0 <= len && len <= SZ); 42 | T res = identity; 43 | for (; len; len -= len & -len) 44 | res = TT(res, data[len]); 45 | return res; 46 | } 47 | 48 | // Returns the result of accumulating the elements at indices in [l, r). Requires InverseOperation be defined. 49 | T accumulate(int l, int r) const { 50 | static_assert(!std::is_same::value, "InverseOperation not defined."); 51 | return l > r ? identity : S(accumulate_prefix(r), accumulate_prefix(l)); 52 | } 53 | 54 | /* Returns the smallest len in [0, S] such that p(accumulate_prefix(len)) returns true. 55 | * Returns S + 1 if no such len exists. 56 | * Requires that p(accumulate_prefix(len)) is non-decreasing in len. 57 | */ 58 | template 59 | int binary_search(Predicate p) const { 60 | if (p(identity)) return 0; 61 | 62 | int len = 0; 63 | T accumulator = identity; 64 | 65 | for (int bit = 31 - __builtin_clz(SZ); bit >= 0; bit--) { 66 | int next = len + (1 << bit); 67 | if (next > SZ) continue; 68 | 69 | T combined = TT(accumulator, data[next]); 70 | if (!p(combined)) { 71 | len = next; 72 | accumulator = combined; 73 | } 74 | } 75 | 76 | return len + 1; 77 | } 78 | }; 79 | -------------------------------------------------------------------------------- /strings/polynomial_hash.cpp: -------------------------------------------------------------------------------- 1 | // {{{ numeric/modnum.cpp }}} 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | template 11 | struct polynomial_hash { 12 | static x_t pow(int point, int exponent) { 13 | static std::vector x(EvaluationPoints, 1); 14 | 15 | if (int(x.size()) == EvaluationPoints) { 16 | x.push_back(AlphabetSize); 17 | 18 | std::mt19937_64 rng(std::chrono::steady_clock::now().time_since_epoch().count()); 19 | 20 | for (int i = 1; i < EvaluationPoints; i++) 21 | x.push_back(AlphabetSize + rng() % std::max(256, AlphabetSize)); 22 | } 23 | 24 | while (exponent * EvaluationPoints + point >= int(x.size())) 25 | for (int i = 0; i < EvaluationPoints; i++) 26 | x.push_back(*(x.end() - EvaluationPoints) * x[EvaluationPoints + i]); 27 | 28 | return x[exponent * EvaluationPoints + point]; 29 | } 30 | 31 | int N; 32 | std::array data; 33 | 34 | polynomial_hash () : N(0) { data.fill(0); } 35 | 36 | polynomial_hash (x_t v) : N(1) { assert(v.v < AlphabetSize); data.fill(v); } 37 | 38 | polynomial_hash (int _N, std::array _data) : N(_N), data(_data) {} 39 | 40 | static polynomial_hash concatenate(polynomial_hash a, polynomial_hash b) { 41 | std::array res; 42 | for (int i = 0; i < EvaluationPoints; i++) 43 | res[i] = a.data[i] * pow(i, b.N) + b.data[i]; 44 | return { a.N + b.N, res }; 45 | } 46 | 47 | bool operator == (const polynomial_hash &o) const { 48 | return N == o.N && data == o.data; 49 | } 50 | 51 | bool operator < (const polynomial_hash &o) const { 52 | return N != o.N ? N < o.N : data < o.data; 53 | } 54 | 55 | friend std::ostream& operator << (std::ostream& o, const polynomial_hash& h) { 56 | o << h.N; 57 | for (int i = 0; i < EvaluationPoints; i++) 58 | o << " " << h.data[i]; 59 | return o; 60 | } 61 | 62 | template 63 | static std::vector get_prefixes(InputIterator begin, InputIterator end) { 64 | std::vector res = { polynomial_hash{} }; 65 | for (InputIterator iter = begin; iter != end; iter = next(iter)) 66 | res.push_back(concatenate(res.back(), polynomial_hash(x_t(*iter)))); 67 | return res; 68 | } 69 | 70 | static polynomial_hash get_substring(const std::vector &prefixes, int first, int last) { 71 | std::array res; 72 | for (int i = 0; i < EvaluationPoints; i++) 73 | res[i] = prefixes[last].data[i] - pow(i, last - first) * prefixes[first].data[i]; 74 | return { last - first, res }; 75 | } 76 | }; 77 | -------------------------------------------------------------------------------- /numeric/matrix_array.cpp: -------------------------------------------------------------------------------- 1 | /* Equivalent to matrix.cpp, but with data stored in std::array. 2 | * Useful when matrix dimensions are known at compile time 3 | * and you want locality for a vector. */ 4 | template struct matrix : array,N> { 5 | matrix (T f = 0, T d = 0) { 6 | for (array& row : *this) row.fill(f); 7 | for (int i = 0; i < min(N, M); i++) ((*this)[i])[i] = d; 8 | } 9 | 10 | matrix (const initializer_list& init) { 11 | assert(sz(init) == N * M); 12 | auto it = init.begin(); 13 | for (array& row : *this) { 14 | copy(it, it + M, row.data()); 15 | it += M; 16 | } 17 | } 18 | 19 | template 20 | friend matrix operator*(const matrix& a, const matrix& b) { 21 | matrix res{}; 22 | for (int i = 0; i < N; i++) 23 | for (int j = 0; j < M; j++) 24 | for (int k = 0; k < M; k++) 25 | res[i][j] += a[i][k] * b[k][j]; 26 | return res; 27 | } 28 | 29 | friend vector operator*(const vector& v, const matrix& m) { 30 | assert(N == sz(v)); 31 | vector res(M); 32 | for (int j = 0; j < M; j++) 33 | for (int i = 0; i < N; i++) 34 | res[j] += v[i] * m[i][j]; 35 | return res; 36 | } 37 | 38 | friend vector operator*(const matrix& m, const vector& v) { 39 | assert(M == sz(v)); 40 | vector res(N); 41 | for (int i = 0; i < N; i++) 42 | for (int j = 0; j < M; j++) 43 | res[i] += m[i][j] * v[j]; 44 | return res; 45 | } 46 | 47 | matrix pow(ll e) const { 48 | assert(N == M); 49 | if (e == 0) return matrix(N, M, 0, 1); 50 | if (e&1) return *this * pow(e - 1); 51 | return (*this * *this).pow(e / 2); 52 | } 53 | 54 | int rank() const { 55 | matrix m = *this; 56 | int r = 0; 57 | for (int j = 0; j < M; j++) { 58 | for (int i = r; i < N; i++) if (m[i][j] != 0) { 59 | swap_ranges(m[r], m[r] + M, m[i]); 60 | break; 61 | } 62 | if (m[r][j] == 0) continue; 63 | 64 | for (int i = 0; i < N; i++) if (i != r) { 65 | T c = m[i][j] / m[r][j]; 66 | for (int k = 0; k < M; k++) 67 | m[i][k] -= c * m[r][k]; 68 | } 69 | r++; 70 | } 71 | return r; 72 | } 73 | 74 | friend ostream& operator <<(ostream& os, const matrix& m) { 75 | for (int i = 0; i < N; i++) { 76 | os << (i ? i < N - 1 ? "\u2503" : "\u2517" : "\n\u250F"); 77 | for (int j = 0; j < M; j++) 78 | os << setw(12) << m[i][j]; 79 | os << " " << (i ? i < m.N - 1 ? "\u2503" : "\u251B" : "\u2512") << "\n"; 80 | } 81 | return os; 82 | } 83 | }; 84 | -------------------------------------------------------------------------------- /test/data_structures/sqrt_decomposition_point_query/duff_is_mad/duff_is_mad.cpp: -------------------------------------------------------------------------------- 1 | // Problem: https://codeforces.com/problemset/problem/587/F 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | // {{{ strings/trie }}} 10 | 11 | // {{{ graphs/tree }}} 12 | 13 | // {{{ data_structures/sqrt_decomposition_point_query }}} 14 | 15 | int main() { 16 | ios_base::sync_with_stdio(false); 17 | cin.tie(0); 18 | 19 | int N, Q; 20 | cin >> N >> Q; 21 | 22 | vector names(N); 23 | for (int i = 0; i < N; i++) 24 | cin >> names[i]; 25 | 26 | vector L(Q), R(Q), K(Q); 27 | 28 | vector> queries(N); 29 | 30 | vector> subtract(N), add(N); 31 | 32 | for (int q = 0; q < Q; q++) { 33 | cin >> L[q] >> R[q] >> K[q]; 34 | --L[q], --R[q], --K[q]; 35 | 36 | if (names[K[q]].size() > 300u) { 37 | queries[K[q]].push_back(q); 38 | } else { 39 | subtract[L[q]].push_back(q); 40 | add[R[q]].push_back(q); 41 | } 42 | } 43 | 44 | vector ans(Q); 45 | 46 | trie<'a', 26> tr(names.begin(), names.end()); 47 | 48 | vector prefixes(N + 1); 49 | 50 | for (int i = 0; i < N; i++) { 51 | if (queries[i].empty()) 52 | continue; 53 | 54 | vector matches = tr.count_matches(names[i].begin(), names[i].end()); 55 | 56 | for (int j = 0; j < N; j++) 57 | prefixes[j + 1] = prefixes[j] + matches[j]; 58 | 59 | for (int q : queries[i]) 60 | ans[q] = prefixes[R[q] + 1] - prefixes[L[q]]; 61 | } 62 | 63 | const int V = int(tr.data.size()); 64 | 65 | tree suffix_link_tree(V, 0); 66 | 67 | for (int i = 1; i < V; i++) 68 | suffix_link_tree.add_edge(i, tr.data[i].suffix_link); 69 | 70 | suffix_link_tree.init(); 71 | 72 | vector preorder_index(V); 73 | 74 | for (int i = 0; i < V; i++) 75 | preorder_index[suffix_link_tree.preorder[i]] = i; 76 | 77 | sqrt_decomposition_point_query st(V, 0, plus()); 78 | 79 | auto sum_trie_path = [&](int w) { 80 | int64_t res = 0; 81 | 82 | int loc = 0; 83 | for (char c : names[w]) { 84 | loc = tr.child_link(loc, c); 85 | res += st.read(preorder_index[loc]); 86 | } 87 | 88 | return res; 89 | }; 90 | 91 | for (int i = 0; i < N; i++) { 92 | for (int q : subtract[i]) 93 | ans[q] -= sum_trie_path(K[q]); 94 | 95 | int v = tr.dictionary_word_links[i]; 96 | st.add_to_range(preorder_index[v], preorder_index[v] + suffix_link_tree.subtree_size[v], 1); 97 | 98 | for (int q : add[i]) 99 | ans[q] += sum_trie_path(K[q]); 100 | } 101 | 102 | for (int64_t v : ans) 103 | cout << v << "\n"; 104 | 105 | return 0; 106 | } 107 | -------------------------------------------------------------------------------- /graphs/dijkstra.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | template 8 | struct WeightedDirectedGraph { 9 | struct Edge { 10 | int neighbor; 11 | EdgeWeight weight; 12 | }; 13 | 14 | int N; 15 | std::vector> adj; 16 | 17 | WeightedDirectedGraph (int _N) : N(_N), adj(_N) {} 18 | 19 | void add_directed_edge(int u, int v, EdgeWeight w) { 20 | adj[u].push_back({v, w}); 21 | } 22 | }; 23 | 24 | template 25 | struct ShortestPathTree { 26 | std::vector parent; 27 | std::vector shortest_path_wt; 28 | 29 | template 30 | ShortestPathTree(WeightedDirectedGraph g, const std::vector &sources, 31 | PathWeight init, JoinPathAndEdge join, PathWeightLessThan less_than) { 32 | struct Path { 33 | int destination; 34 | PathWeight weight; 35 | }; 36 | 37 | auto path_cmp = [&less_than](const Path &a, const Path &b) { 38 | return less_than(b.weight, a.weight); 39 | }; 40 | 41 | std::priority_queue, decltype(path_cmp)> pq(path_cmp); 42 | 43 | parent.assign(g.N, -1); 44 | shortest_path_wt.assign(g.N, init); 45 | 46 | for (int source : sources) { 47 | parent[source] = source; 48 | pq.push({ source, shortest_path_wt[source] }); 49 | } 50 | 51 | while (!pq.empty()) { 52 | Path path = pq.top(); 53 | pq.pop(); 54 | 55 | if (memcmp(&path.weight, &shortest_path_wt[path.destination], sizeof(PathWeight))) 56 | continue; 57 | 58 | for (auto edge : g.adj[path.destination]) { 59 | PathWeight candidate = join(path.weight, edge.weight); 60 | if (parent[edge.neighbor] == -1 || less_than(candidate, shortest_path_wt[edge.neighbor])) { 61 | parent[edge.neighbor] = path.destination; 62 | shortest_path_wt[edge.neighbor] = candidate; 63 | pq.push({ edge.neighbor, shortest_path_wt[edge.neighbor] }); 64 | } 65 | } 66 | } 67 | } 68 | 69 | bool is_reachable(int destination) const { 70 | return parent[destination] != -1; 71 | } 72 | 73 | PathWeight distance(int destination) const { 74 | if (!is_reachable(destination)) assert(false); 75 | return shortest_path_wt[destination]; 76 | } 77 | 78 | std::vector list_vertices_on_path(int destination) const { 79 | if (!is_reachable(destination)) assert(false); 80 | 81 | std::vector path; 82 | while (parent[destination] != destination) { 83 | path.push_back(destination); 84 | destination = parent[destination]; 85 | } 86 | path.push_back(destination); 87 | 88 | std::reverse(path.begin(), path.end()); 89 | return path; 90 | } 91 | }; 92 | -------------------------------------------------------------------------------- /graphs/min_cost_flow.cpp: -------------------------------------------------------------------------------- 1 | template struct min_cost_flow { 2 | static constexpr int bits = 63 - __builtin_clzll(numeric_limits::max()); 3 | 4 | int V, E; 5 | vvi adj; 6 | vi dest; 7 | vector cap; 8 | vector cost; 9 | 10 | min_cost_flow(int V_ = 0) : V(V_), E(0) { 11 | adj.resize(V); 12 | } 13 | 14 | void __arc(int u, int v, F f, C c) { 15 | E++; 16 | adj[u].push_back(sz(dest)); 17 | dest.push_back(v); 18 | cap.push_back(f); 19 | cost.push_back(c); 20 | } 21 | 22 | // Inserts a directed edge u --> v with capacity f and cost c. 23 | void arc(int u, int v, F f, C c) { 24 | __arc(u, v, f, c); 25 | __arc(v, u, F(0), -c); 26 | } 27 | 28 | bool dijkstra(auto& imb, auto& flow, auto& pot, F delta) const { 29 | priority_queue> q; 30 | vi ent(V, -2); 31 | vector dist(V, numeric_limits::max()); 32 | for (int v = 0; v < V; v++) if (imb[v] >= delta) { 33 | dist[v] = 0; 34 | q.push(make_tuple(0., v, -1)); 35 | } 36 | 37 | while (!q.empty()) { 38 | C d; int v, f; tie(d, v, f) = q.top(); q.pop(); 39 | if (ent[v] != -2) continue; 40 | dist[v] = -d; ent[v] = f; 41 | for (int e : adj[v]) if (cap[e] - flow[e] >= delta) { 42 | C cd = dist[v] + (cost[e] + pot[v] - pot[dest[e]]); 43 | if (cd < dist[dest[e]]) { 44 | dist[dest[e]] = cd; 45 | q.push(make_tuple(-cd, dest[e], e )); 46 | } 47 | } 48 | } 49 | 50 | for (int v = 0; v < V; v++) if (ent[v] != -2 && imb[v] <= -delta) { 51 | for (int u = 0; u < V; u++) 52 | if (ent[u] != -2) pot[u] += dist[u]; 53 | for (int e = ent[v]; ~e; e = ent[dest[e^1]]) { 54 | flow[e] += delta; 55 | flow[e^1] -= delta; 56 | imb[dest[e]] += delta; 57 | imb[dest[e^1]] -= delta; 58 | } 59 | return true; 60 | } 61 | return false; 62 | } 63 | 64 | // Computes the minimum cost to satisfy the specified imbalances. 65 | // Runs in O(E^2 * log V * log inf). 66 | struct circulation { 67 | bool feasible; 68 | C cost; 69 | vector flow; 70 | }; 71 | circulation solve(vector imb) const { 72 | vector flow(E); 73 | vector pot(V); 74 | for (F delta = 1ll << bits; delta; delta >>= 1) { 75 | for (int e = 0; e < E; e++) { 76 | int u = dest[e^1], v = dest[e]; 77 | F res = cap[e] - flow[e]; 78 | if (res >= delta && cost[e] + pot[u] - pot[v] < 0) { 79 | flow[e^1] -= res; 80 | flow[e] += res; 81 | imb[u] -= res; 82 | imb[v] += res; 83 | } 84 | } 85 | while (dijkstra(imb, flow, pot, delta)); 86 | } 87 | 88 | C ans = 0; 89 | for (int e = 0; e < E; e++) if (flow[e] > 0) { 90 | ans += flow[e] * cost[e]; 91 | } 92 | return { imb == vector(V, 0), ans, flow }; 93 | } 94 | }; 95 | -------------------------------------------------------------------------------- /numeric/frac.cpp: -------------------------------------------------------------------------------- 1 | template struct frac { 2 | v_t n, d; 3 | frac(v_t _n, v_t _d = 1) : n(_n), d(_d) { 4 | assert(n != 0 || d != 0); 5 | if (d < 0) { n *= -1; d *= -1; } 6 | v_t g = gcd(abs(n), d); 7 | n /= g; 8 | d /= g; 9 | } 10 | friend ostream& operator << (ostream& o, const frac& f) { 11 | return o << f.n << "/" << f.d; 12 | } 13 | 14 | #define define_relational_operator(OP) \ 15 | friend bool operator OP (const frac& a, const frac& b) { \ 16 | return a.n * b.d OP b.n * a.d; \ 17 | } 18 | define_relational_operator(<) 19 | define_relational_operator(<=) 20 | define_relational_operator(==) 21 | define_relational_operator(!=) 22 | define_relational_operator(>) 23 | define_relational_operator(>=) 24 | 25 | friend frac min(const frac a, const frac b) { return a <= b ? a : b; } 26 | friend frac max(const frac a, const frac b) { return a >= b ? a : b; } 27 | 28 | frac& operator += (const frac& b) { return *this = frac(n*b.d+b.n*d, d*b.d); } 29 | frac& operator -= (const frac& b) { return *this = frac(n*b.d-b.n*d, d*b.d); } 30 | frac& operator *= (const frac& b) { return *this = frac(n*b.n, d*b.d); } 31 | frac& operator /= (const frac& b) { return *this = frac(n*b.d, d*b.n); } 32 | friend frac operator + (const frac& a, const frac& b) { return frac(a) += b; } 33 | friend frac operator - (const frac& a, const frac& b) { return frac(a) -= b; } 34 | friend frac operator * (const frac& a, const frac& b) { return frac(a) *= b; } 35 | friend frac operator / (const frac& a, const frac& b) { return frac(a) /= b; } 36 | 37 | explicit operator double() const { return double(n)/d; } 38 | v_t floor() { assert(d > 0); return n / d - ((n < 0) && (n % d)); } 39 | v_t ceil() { assert(d > 0); return n / d + ((n > 0) && (n % d)); } 40 | 41 | // canonical continued fraction 42 | vector to_cont() const { 43 | if (d == 0) return { LLONG_MAX }; 44 | vector cont; 45 | for (v_t n = this->n, d = this->d; ; swap(n, d)) { 46 | v_t f = (n >= 0 ? n : n - d + 1) / d; 47 | cont.push_back(f); 48 | n -= f * d; 49 | if (n == 0) break; 50 | } 51 | return cont; 52 | } 53 | 54 | static frac from_cont(const vector& cont) { 55 | v_t n = 1, d = 0; 56 | for (int i = int(cont.size()) - 1; i >= 0; i--) { 57 | swap(n, d); 58 | n += d * cont[i]; 59 | } 60 | return { n, d }; 61 | } 62 | 63 | // "best" fraction in (x, y): minimizes both n and d 64 | friend frac best_in(const frac x, const frac y) { 65 | assert(x < y); 66 | 67 | vector x1 = x.to_cont(), y1 = y.to_cont(); 68 | vector x2 = x1; x2.back()--; x2.push_back(1); 69 | vector y2 = y1; y2.back()--; y2.push_back(1); 70 | 71 | auto z = [](const vector& a, const vector& b) { 72 | vector c; 73 | for (int i = 0; ; i++) { 74 | v_t ai = i < a.size() ? a[i] : LLONG_MAX; 75 | v_t bi = i < b.size() ? b[i] : LLONG_MAX; 76 | if (ai != bi) { 77 | c.push_back(min(ai, bi) + 1); 78 | return from_cont(c); 79 | } 80 | c.push_back(ai); 81 | } 82 | }; 83 | 84 | frac ans = { 1, 0 }; 85 | for (const frac f : {z(x1, y1), z(x1, y2), z(x2, y1), z(x2, y2)}) { 86 | if (x < f && f < y && (ans.d == 0 || f.d < ans.d)) 87 | ans = f; 88 | } 89 | return ans; 90 | } 91 | }; 92 | -------------------------------------------------------------------------------- /numeric/matrix.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | template 7 | struct matrix { 8 | int N, M; 9 | std::vector data; 10 | 11 | matrix(int _N, int _M, T value = T{}) : N(_N), M(_M), data(N * M, value) {} 12 | matrix(int _N, int _M, T value, T diag) : N(_N), M(_M), data(N * M, value) { 13 | for (int i = 0; i < int(data.size()); i += M + 1) data[i] = diag; 14 | } 15 | 16 | typename std::vector::iterator operator[](int i) { 17 | return data.begin() + i * M; 18 | } 19 | typename std::vector::const_iterator operator[](int i) const { 20 | return data.begin() + i * M; 21 | } 22 | 23 | friend matrix operator * (const matrix& a, const matrix& b) { 24 | assert(a.M == b.N); 25 | matrix res(a.N, b.M); 26 | for (int i = 0; i < a.N; i++) 27 | for (int k = 0; k < a.M; k++) 28 | for (int j = 0; j < b.M; j++) 29 | res[i][j] += a[i][k] * b[k][j]; 30 | return res; 31 | } 32 | 33 | friend std::vector operator * (const std::vector& v, const matrix& m) { 34 | assert(sz(v) == m.N); 35 | std::vector res(m.M); 36 | for (int i = 0; i < m.N; i++) 37 | for (int j = 0; j < m.M; j++) 38 | res[j] += v[i] * m[i][j]; 39 | return res; 40 | } 41 | 42 | friend std::vector operator * (const matrix& m, const std::vector& v) { 43 | assert(m.M == sz(v)); 44 | std::vector res(m.N); 45 | for (int i = 0; i < m.N; i++) 46 | for (int j = 0; j < m.M; j++) 47 | res[i] += m[i][j] * v[j]; 48 | return res; 49 | } 50 | 51 | matrix pow(int64_t e) const { 52 | assert(N == M); 53 | if (e == 0) return matrix(N, N, 0, 1); 54 | if (e&1) return *this * pow(e - 1); 55 | return (*this * *this).pow(e / 2); 56 | } 57 | 58 | friend void row_reduce(matrix &m) { 59 | int rank = 0; 60 | for (int j = 0; j < m.M && rank < m.N; j++) { 61 | for (int i = rank; i < m.N; i++) { 62 | if (m[i][j] != 0) { 63 | swap_ranges(m[rank], m[rank] + m.M, m[i]); 64 | break; 65 | } 66 | } 67 | if (m[rank][j] == 0) 68 | continue; 69 | 70 | T inv = 1 / m[rank][j]; 71 | for (int k = j; k < m.M; k++) 72 | m[rank][k] *= inv; 73 | 74 | for (int i = 0; i < m.N; i++) { 75 | if (i != rank) { 76 | T c = m[i][j]; 77 | for (int k = j; k < m.M; k++) 78 | m[i][k] -= c * m[rank][k]; 79 | } 80 | } 81 | rank++; 82 | } 83 | 84 | m.N = rank; 85 | m.data.resize(m.N * m.M); 86 | } 87 | 88 | friend std::ostream& operator << (std::ostream& os, const matrix& m) { 89 | for (int i = 0; i < m.N; i++) { 90 | os << (i ? i < m.N - 1 ? "\u2503" : "\u2517" : "\n\u250F"); 91 | for (int j = 0; j < m.M; j++) 92 | os << std::setw(12) << m[i][j]; 93 | os << " " << (i ? i < m.N - 1 ? "\u2503" : "\u251B" : "\u2512") << "\n"; 94 | } 95 | return os; 96 | } 97 | 98 | friend std::istream& operator >> (std::istream& is, const matrix& m) { 99 | for (int i = 0; i < m.N; i++) { 100 | for (int j = 0; j < m.M; j++) 101 | is >> m[i][j]; 102 | } 103 | return is; 104 | } 105 | }; 106 | -------------------------------------------------------------------------------- /numeric/bignum_addpow2_compare.cpp: -------------------------------------------------------------------------------- 1 | // {{{ strings/polynomial_hash }}} 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | struct bignum_addpow2_compare { 8 | using hash_t = polynomial_hash, 3, 2>; 9 | 10 | struct binary_string { 11 | hash_t hash; 12 | int ct_trailing_ones; 13 | int left, right; 14 | 15 | binary_string(bool bit) : hash(bit), ct_trailing_ones(bit), left(-1), right(-1) {} 16 | 17 | binary_string(hash_t _hash, int _ct_trailing_ones, int _left, int _right) 18 | : hash(_hash), ct_trailing_ones(_ct_trailing_ones), left(_left), right(_right) {} 19 | 20 | int length() const { return hash.N; } 21 | bool is_all_ones() const { return hash.N == ct_trailing_ones; } 22 | }; 23 | 24 | std::vector nums = { binary_string(0), binary_string(1) }; 25 | 26 | const int one = 1; 27 | std::vector zero = { 0 }; 28 | 29 | int concatenate(int x, int y) { 30 | nums.emplace_back( 31 | hash_t::concatenate(nums[x].hash, nums[y].hash), 32 | nums[y].ct_trailing_ones + (nums[y].is_all_ones() ? nums[x].ct_trailing_ones : 0), 33 | x, 34 | y 35 | ); 36 | return int(nums.size()) - 1; 37 | } 38 | 39 | int get_zero_of_width(int bit_width) { 40 | int index = __builtin_ctz(bit_width); 41 | while (index >= int(zero.size())) 42 | zero.push_back(concatenate(zero.back(), zero.back())); 43 | return zero[index]; 44 | } 45 | 46 | int carry_count(int x, int pow) const { 47 | const int len = nums[x].length(); 48 | 49 | if (len <= pow) 50 | return 0; 51 | 52 | if (nums[x].is_all_ones()) 53 | return len - pow; 54 | 55 | if (len == 1) 56 | return nums[x].ct_trailing_ones; 57 | 58 | int res = carry_count(nums[x].right, pow); 59 | 60 | if (pow + res >= len / 2) 61 | res += carry_count(nums[x].left, pow + res - len / 2); 62 | 63 | return res; 64 | } 65 | 66 | int invert_range(int x, int L, int R) { 67 | const int len = nums[x].length(); 68 | assert(0 <= L && L < R && R <= len); 69 | 70 | if (len == 1) 71 | return x ^ 1; 72 | 73 | if (0 == L && R == len && nums[x].is_all_ones()) 74 | return get_zero_of_width(len); 75 | 76 | int right = L < len / 2 ? invert_range(nums[x].right, L, std::min(R, len / 2)) : nums[x].right; 77 | int left = R > len / 2 ? invert_range(nums[x].left, std::max(0, L - len / 2), R - len / 2) : nums[x].left; 78 | 79 | return concatenate(left, right); 80 | } 81 | 82 | int add_pow2(int x, int pow) { 83 | int carries = carry_count(x, pow); 84 | while (nums[x].length() <= pow + carries) 85 | x = concatenate(get_zero_of_width(nums[x].length()), x); 86 | return invert_range(x, pow, pow + carries + 1); 87 | } 88 | 89 | bool less_than(int x, int y) const { 90 | if (nums[x].length() != nums[y].length()) 91 | return nums[x].length() < nums[y].length(); 92 | 93 | if (nums[x].length() == 1) 94 | return nums[x].ct_trailing_ones < nums[y].ct_trailing_ones; 95 | 96 | if (nums[nums[x].left].hash == nums[nums[y].left].hash) 97 | return less_than(nums[x].right, nums[y].right); 98 | 99 | return less_than(nums[x].left, nums[y].left); 100 | } 101 | 102 | void print_bits(int x) const { 103 | if (nums[x].length() == 1) { 104 | std::cout << nums[x].ct_trailing_ones; 105 | } else { 106 | print_bits(nums[x].left); 107 | print_bits(nums[x].right); 108 | } 109 | } 110 | }; 111 | -------------------------------------------------------------------------------- /test/numeric/ntt/convolution_mod_998244353/tests/sample3.out: -------------------------------------------------------------------------------- 1 | 487754382 454306984 788978428 217183831 236205514 515263230 168018841 687116062 819923078 386372388 890152860 489553431 320886778 54951374 86304969 821054429 946769751 185229144 30447709 631646058 615591354 573164124 40932826 261981452 439187169 896123413 93401922 563221835 114861812 44055593 398950569 672372116 235844766 622234770 936629263 961169074 383970533 239676342 546255480 528361188 687325924 109145751 474218785 39025566 209515742 85479450 622355270 341620740 147684410 309766111 888239348 997207078 975727549 916291112 949553030 198148293 806080985 25204704 686102601 657693225 962575823 740169855 89265805 70979707 506261329 937019653 20011794 739240566 377546976 620943338 717377477 707765723 38460161 688214449 744420494 258084632 520989910 733453413 361338847 307445182 190099185 421157438 152356983 341154220 591153706 204067425 36265826 137670370 688755291 351058105 114468682 355554517 83991484 32412037 751872809 700296052 766768423 860001028 288038444 520687212 329968345 538692186 855247496 179294167 836934275 565904055 725933850 123313289 226475798 891641833 193465585 501708159 774895473 771086448 599936606 249984249 781306278 408963413 880773017 203370570 162023048 854994069 825760505 529182131 438292789 65505312 95022284 282247584 556051591 242943567 633082079 316462326 791047575 542201516 543703129 916471955 739279659 419152400 975910725 457745339 556814506 531406798 705561612 51726103 565326933 972095966 111359655 194269637 432039483 201409325 452219340 744933 1399425 841572934 674922548 707112795 213369259 913458612 857023069 789070460 26297761 314424398 571934359 575855661 455229990 202359375 568199957 186978630 778487445 960633990 639239370 316801516 182075290 19387036 705465371 467664077 662455551 875259029 996777241 775561219 686931073 736264192 92678691 845773930 568334425 501059625 957808299 537301833 488910997 653171271 227603619 370637998 868361907 941461847 356507463 618729961 259132006 158234641 400046271 43821706 429666588 398594935 908292527 383803930 583689878 767593995 325846009 530320276 832526521 829955062 77490124 435997953 503708429 179233508 626655506 566210480 727522401 383588044 656782981 67490884 709484798 839257720 262557257 56572109 966293142 448418817 266562162 495059620 201034903 852170027 417252836 950992680 840782336 869518606 683815116 462513935 890869754 99014212 533167369 691661301 400050767 131181004 61010426 344134453 466350953 115433568 63118915 879105539 497613737 996420429 430072876 308300125 793251049 408288212 406149677 601816511 689283511 527190914 940842571 943442240 473752815 847236511 47494075 238001066 247010116 859729907 384241325 55167015 709013678 215318442 682159030 257997708 445780366 775989932 308282984 519634523 473207044 196345353 606776887 945148937 283547142 552016720 606441031 506856432 875246383 428827434 108781278 972549533 338021208 317752795 88807922 228442403 208580336 860190090 514036845 535533044 192754101 666907399 602976348 285923994 75610080 592170371 542481802 508461385 955534278 776214442 238877989 32174655 828585556 78681824 849337666 801818256 204193743 215206521 105006437 78075389 750890812 706940036 270661145 861008131 223575098 964020275 251698507 796835286 876771384 895985541 180093298 571917463 751915709 233714990 986973024 958294281 547091819 829185649 146114831 455585665 237226364 896545081 517118185 505461440 994319830 201189658 39908256 830835522 649985394 370591627 56873214 476698564 63784635 629364928 697289950 732288692 93037901 17750389 127950155 169313023 314748473 662418176 949894044 762112990 112117975 735039427 276907267 387512771 779006952 900775491 969224030 892115576 521148221 63416149 921389114 358233086 396037385 815136470 372085557 905682216 743169430 779028750 410570037 54385016 507733221 303592254 201364801 631030899 726906210 345052912 545198870 439759682 115080082 44093535 457789634 610684695 142138357 11562035 370931214 345083651 689008963 498206579 695381616 2 | -------------------------------------------------------------------------------- /test/numeric/complex_fft/convolution_mod_1000000007/tests/sample3.out: -------------------------------------------------------------------------------- 1 | 112293921 465032562 161038473 298013499 776941454 709397788 931536523 95012362 125438542 355080441 985687672 743360764 260750171 700601939 208399892 580944783 206851362 444558460 887971900 120541259 31277035 298652580 100938845 124919798 272908001 153074898 812229298 502171996 873795470 477192977 730087592 30019702 738047489 235319569 200700261 380006873 396339893 857505395 862507902 774467444 65931660 923580933 72033461 195171191 266650115 753633694 458477229 888911827 764054906 555363155 723912936 368057554 193999923 52061580 338370932 349625338 381946739 177264110 142882379 430112828 315968776 165363865 479270120 338792644 507233205 859462192 911136229 570953329 720518894 7801279 188306798 671095931 598343736 501432281 434535259 357871371 153066128 754732355 676034377 53241359 593248963 421088074 8163987 668576605 891502202 665090050 608166116 498707031 221895271 221838059 29613887 273686821 920679573 266356577 770251537 695318355 367026417 925033645 279256466 106425944 20891487 638292995 819568398 402666107 948594659 478300910 604855717 966018373 481046373 119812820 472962727 642950864 558042596 270484564 875857729 145079657 520530047 720694332 161207825 919940340 929611674 461540535 465842634 83661094 854986389 304387540 112909789 248277459 342109235 543761488 514799659 833790552 239275320 989722149 225174711 659060809 193536137 78551361 258955666 174453212 862896217 683554224 850158723 805549595 707145149 729830419 618053567 151800733 347027383 731667378 233527492 456767695 373858076 544055552 809938597 928662671 509506628 27431381 573770278 44827027 916529507 42658620 681165938 905919700 385938872 23576389 424866950 253171692 526628853 190650471 111324925 129758846 687902248 547935464 16695762 293571054 684381464 812437600 914997944 712854987 284149247 307418490 551820135 925739988 949826041 640387681 594509201 720780107 872811404 296429784 841688525 123965309 965562074 863541768 932807102 552195597 223483465 427079661 687694581 184705404 798620610 521778357 848495729 670612560 359577852 522478390 853104642 645256924 928651415 803372016 59048683 736948483 46690176 313956465 158532589 199658868 736253729 872669222 220832750 228963328 425794150 94069676 665404811 315919828 694714237 169787263 288369137 773685371 948470880 127248333 497468076 789766376 582818850 979051758 901907084 609436041 518266116 809572285 557769374 366453217 473875327 159430394 564620370 269546967 920880138 481012145 984429199 463919056 866284601 597916481 761886820 891271551 130246575 800557368 261439053 792490358 528488547 57239903 897328439 580543360 236905856 35338748 18270932 509520394 696733536 764913118 793570150 756118001 462121056 384442416 490576591 130958576 556926927 247682068 256141648 682784265 109599727 742643869 790916470 112231920 213561894 144359172 106061246 880352643 996170465 269606740 551025215 473971459 772527773 175636829 591603743 746796780 43387426 514401636 80492012 805082288 271612126 8459945 371081540 108217668 350514768 332708746 232967510 160331003 621530889 115798058 868455398 215941284 723609173 499796047 258925890 433785528 588361786 450740243 692362819 11296714 592344870 259898810 240947259 419832134 260235744 222484760 4208825 72689789 46035060 81638854 812864569 160985828 706362767 928486840 244372425 430086929 176535396 710992112 862321575 820583573 856945523 854869240 975410240 743034647 113533398 438800813 234466063 756484583 187169338 567564576 237147468 599373834 280272959 181792931 618357743 201237944 164354678 539159835 798586857 187564103 686835256 87893655 940126363 142566158 333117338 362124694 75245237 217609085 781850640 755977692 90351456 375499497 64707135 842519239 915725461 407719092 53822718 869659879 114527598 732081955 414211334 199620287 564959105 493844767 795424808 593398827 489544218 290162920 472705430 72447543 452301609 515697477 795626443 319038699 905132651 52702303 853338267 439237667 451283719 104319536 471870923 630810160 673781081 2 | -------------------------------------------------------------------------------- /test/numeric/ntt/convolution_mod_998244353/tests/sample3.in: -------------------------------------------------------------------------------- 1 | 200 200 2 | 824660501 185312087 454873885 10168203 434864812 543681060 333662832 812544599 57354450 280300861 809092161 955002829 932346590 652430335 424640554 231331881 360897022 525908730 13562923 368565206 225426356 597209733 700087171 303296595 351480477 767825480 873622972 657111530 829312940 422814577 382465578 854450848 346930297 295211129 403147227 470130758 939160735 93282902 366280544 984442508 879770569 623910299 398956257 332723576 261817369 218847364 158556475 336288066 883816659 958755128 751194628 120110127 182592461 527385876 695900587 389601780 127240662 217548807 875812694 244815814 482330848 726524747 692069765 387408287 874329698 88901479 265729580 802118865 900941249 413971757 737241793 302306429 260045640 504885265 819894354 519070025 305283468 380483374 330959861 253166788 448026204 907053639 642285053 799179847 529792164 721667754 365205554 457662839 598141673 693756199 800410663 117450307 269492231 568466140 888350150 586448971 820228238 983453744 795229903 948693095 77707823 510126274 919417763 864654273 309311153 83900138 181520155 210533842 112560109 772211518 422801823 792398952 191945820 821149552 434863212 374939147 645866051 299596176 208145181 77231104 548257134 999472873 978417179 459916900 436761 379988673 609849592 206662142 337906273 884026686 752895455 933287107 684545309 174334650 100820007 518772384 650895853 538461995 365105019 798806237 588435422 981722965 724088171 876321399 769061262 782804397 297949541 136206740 777604613 551145644 352321705 502512784 50990572 267391730 903667759 818386288 112073684 143204982 271472775 267354193 848564621 98818140 723120591 18765467 962246456 39541558 584243736 67323784 911729171 128558476 943849562 593846710 53453938 19993928 663946620 14231337 810230231 138986003 787244240 637163696 352299056 832651759 379527795 628561160 711378002 167723602 475831331 103189274 463897234 265869604 591158518 965711838 897892710 242026414 209190543 141303647 788225794 544905451 590610989 102451694 3 | 648914921 727828028 133011456 332874928 658976630 335657325 584345535 318484885 604309848 477584286 85753358 947739010 254363853 979903972 707851908 759102465 987622398 142414162 535565112 717966366 178392037 273712865 127659009 295418500 214741351 192942320 843283259 847652816 419000727 352260958 956702352 146655991 300117995 227230105 401666314 756259028 490173583 114263301 211196795 895878453 275404222 580978010 676190088 315877778 632649275 371625465 23255996 217807931 244590717 642694247 814226316 858966124 619213962 115113691 340507217 197939929 711586375 42178252 399681610 608614586 675685978 270418617 115359826 836805500 265629653 282805080 486596852 159567835 741261946 281628318 910179537 76169711 283135919 869082342 415766330 363585299 902278267 412443736 837584515 845061955 917497158 794298094 798527730 748784961 304070878 836445725 135982812 308828718 529260822 139439869 112056779 29584886 227161812 860808491 276429579 106132315 970549611 71134496 816855916 29202046 891821653 948940361 255961009 898101965 132463506 494914374 192230926 385763037 961769490 710799777 153986889 382959061 408371050 306860147 234695854 830162133 285933311 265204457 613891838 327271527 956667885 138317531 732610400 627818207 168106631 489567910 27142413 596684083 647927625 588161019 16564628 665674690 659534494 970931607 565822356 96288545 514346724 528687841 864143346 335364864 921078380 50246176 67585210 846853057 289205047 563788537 73274639 563614498 246344469 956182116 995835854 897594198 412300625 846741281 611936175 838744865 503763467 433159744 573779821 436811289 415632051 244769780 719175063 200472235 487666533 937371447 915374376 622804771 710065762 441183721 777196904 439573647 821735419 357246161 264703318 719320610 129604536 653442994 660125222 728408807 965016170 71258602 495998619 198481416 505285533 951903075 166285469 459064929 8814270 945863904 164549739 927605787 347629795 37203221 528713922 374020986 415294031 109710046 885123259 7364736 4 | -------------------------------------------------------------------------------- /test/numeric/complex_fft/convolution_mod_1000000007/tests/sample3.in: -------------------------------------------------------------------------------- 1 | 200 200 2 | 824660501 185312087 454873885 10168203 434864812 543681060 333662832 812544599 57354450 280300861 809092161 955002829 932346590 652430335 424640554 231331881 360897022 525908730 13562923 368565206 225426356 597209733 700087171 303296595 351480477 767825480 873622972 657111530 829312940 422814577 382465578 854450848 346930297 295211129 403147227 470130758 939160735 93282902 366280544 984442508 879770569 623910299 398956257 332723576 261817369 218847364 158556475 336288066 883816659 958755128 751194628 120110127 182592461 527385876 695900587 389601780 127240662 217548807 875812694 244815814 482330848 726524747 692069765 387408287 874329698 88901479 265729580 802118865 900941249 413971757 737241793 302306429 260045640 504885265 819894354 519070025 305283468 380483374 330959861 253166788 448026204 907053639 642285053 799179847 529792164 721667754 365205554 457662839 598141673 693756199 800410663 117450307 269492231 568466140 888350150 586448971 820228238 983453744 795229903 948693095 77707823 510126274 919417763 864654273 309311153 83900138 181520155 210533842 112560109 772211518 422801823 792398952 191945820 821149552 434863212 374939147 645866051 299596176 208145181 77231104 548257134 999472873 978417179 459916900 436761 379988673 609849592 206662142 337906273 884026686 752895455 933287107 684545309 174334650 100820007 518772384 650895853 538461995 365105019 798806237 588435422 981722965 724088171 876321399 769061262 782804397 297949541 136206740 777604613 551145644 352321705 502512784 50990572 267391730 903667759 818386288 112073684 143204982 271472775 267354193 848564621 98818140 723120591 18765467 962246456 39541558 584243736 67323784 911729171 128558476 943849562 593846710 53453938 19993928 663946620 14231337 810230231 138986003 787244240 637163696 352299056 832651759 379527795 628561160 711378002 167723602 475831331 103189274 463897234 265869604 591158518 965711838 897892710 242026414 209190543 141303647 788225794 544905451 590610989 102451694 3 | 648914921 727828028 133011456 332874928 658976630 335657325 584345535 318484885 604309848 477584286 85753358 947739010 254363853 979903972 707851908 759102465 987622398 142414162 535565112 717966366 178392037 273712865 127659009 295418500 214741351 192942320 843283259 847652816 419000727 352260958 956702352 146655991 300117995 227230105 401666314 756259028 490173583 114263301 211196795 895878453 275404222 580978010 676190088 315877778 632649275 371625465 23255996 217807931 244590717 642694247 814226316 858966124 619213962 115113691 340507217 197939929 711586375 42178252 399681610 608614586 675685978 270418617 115359826 836805500 265629653 282805080 486596852 159567835 741261946 281628318 910179537 76169711 283135919 869082342 415766330 363585299 902278267 412443736 837584515 845061955 917497158 794298094 798527730 748784961 304070878 836445725 135982812 308828718 529260822 139439869 112056779 29584886 227161812 860808491 276429579 106132315 970549611 71134496 816855916 29202046 891821653 948940361 255961009 898101965 132463506 494914374 192230926 385763037 961769490 710799777 153986889 382959061 408371050 306860147 234695854 830162133 285933311 265204457 613891838 327271527 956667885 138317531 732610400 627818207 168106631 489567910 27142413 596684083 647927625 588161019 16564628 665674690 659534494 970931607 565822356 96288545 514346724 528687841 864143346 335364864 921078380 50246176 67585210 846853057 289205047 563788537 73274639 563614498 246344469 956182116 995835854 897594198 412300625 846741281 611936175 838744865 503763467 433159744 573779821 436811289 415632051 244769780 719175063 200472235 487666533 937371447 915374376 622804771 710065762 441183721 777196904 439573647 821735419 357246161 264703318 719320610 129604536 653442994 660125222 728408807 965016170 71258602 495998619 198481416 505285533 951903075 166285469 459064929 8814270 945863904 164549739 927605787 347629795 37203221 528713922 374020986 415294031 109710046 885123259 7364736 4 | -------------------------------------------------------------------------------- /data_structures/segment_tree_persistent.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | template 7 | struct segment_tree_persistent { 8 | struct node { 9 | T v; 10 | int left, right; 11 | }; 12 | struct snapshot { 13 | Timestamp t; 14 | int root; 15 | int data_size; 16 | bool operator < (const snapshot &o) const { return t < o.t; } 17 | }; 18 | 19 | int SZ; 20 | T identity; 21 | AssociativeOperation TT; 22 | std::vector data; 23 | std::vector history; 24 | 25 | segment_tree_persistent() {} 26 | 27 | segment_tree_persistent(int _SZ, T _identity, AssociativeOperation _TT) : identity(_identity), TT(_TT) { 28 | SZ = 1 << (32 - __builtin_clz(_SZ - 1)); 29 | assert(SZ >= _SZ && __builtin_popcount(SZ) == 1); 30 | 31 | data.push_back({ identity, -1, -1 }); 32 | for (int loc = 1; loc <= __builtin_ctz(SZ); loc++) 33 | data.push_back({ TT(data[loc - 1].v, data[loc - 1].v), loc - 1, loc - 1 }); 34 | 35 | history.push_back({ std::numeric_limits::min(), int(data.size()) - 1, int(data.size()) }); 36 | } 37 | 38 | private: 39 | int modify_leaf(int i, T v, int loc, int L, int R, int immutable, bool overwrite) { 40 | node updated; 41 | if (R - L == 1) { 42 | updated = { overwrite ? v : TT(data[loc].v, v), -1, -1 }; 43 | } else { 44 | int M = L + (R - L) / 2; 45 | int left = i < M ? modify_leaf(i, v, data[loc].left, L, M, immutable, overwrite) : data[loc].left; 46 | int right = M <= i ? modify_leaf(i, v, data[loc].right, M, R, immutable, overwrite) : data[loc].right; 47 | updated = { TT(data[left].v, data[right].v), left, right }; 48 | } 49 | if (loc < immutable) { 50 | loc = int(data.size()); 51 | data.push_back(updated); 52 | } else { 53 | data[loc] = updated; 54 | } 55 | return loc; 56 | } 57 | 58 | void modify_leaf(int i, T v, Timestamp t, bool overwrite) { 59 | int current_root = history.back().root; 60 | if (history.back().t == t) history.pop_back(); 61 | 62 | int immutable = history.back().data_size; 63 | int updated_root = modify_leaf(i, v, current_root, 0, SZ, immutable, overwrite); 64 | history.push_back({ t, updated_root, int(data.size()) }); 65 | } 66 | 67 | T accumulate(int i, int j, T init, int loc, int L, int R) const { 68 | if (L == i && j == R) { 69 | init = TT(init, data[loc].v); 70 | } else { 71 | int M = L + (R - L) / 2; 72 | if (i < M) init = accumulate(i, std::min(j, M), init, data[loc].left, L, M); 73 | if (M < j) init = accumulate(std::max(i, M), j, init, data[loc].right, M, R); 74 | } 75 | return init; 76 | } 77 | 78 | public: 79 | // Assigns v at index i during moment t 80 | void assign(int i, T v, Timestamp t) { 81 | assert(0 <= i && i < SZ && history.back().t <= t); 82 | modify_leaf(i, v, t, true); 83 | } 84 | 85 | // Replaces the current value at index i with TT(current value, v) during moment t 86 | void combine_and_assign(int i, T v, Timestamp t) { 87 | assert(0 <= i && i < SZ && history.back().t <= t); 88 | modify_leaf(i, v, t, false); 89 | } 90 | 91 | // Accumulates the elements at indices in [first, last) as they were before t (after all assignments with t' < t) 92 | T accumulate(int first, int last, Timestamp t) const { 93 | if (first >= last) return identity; 94 | assert(0 <= first && last <= SZ); 95 | int root_before_t = std::prev(std::lower_bound(history.begin(), history.end(), snapshot{ t, -1, -1 }))->root; 96 | return accumulate(first, last, identity, root_before_t, 0, SZ); 97 | } 98 | }; 99 | -------------------------------------------------------------------------------- /data_structures/segment_tree_lazy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 8 | struct segment_tree_lazy { 9 | int SZ; 10 | T t_identity; 11 | U u_identity; 12 | TAssociativeCombineFunction TT; 13 | UAssociativeCombineFunction UU; 14 | UApplicator UT; 15 | 16 | std::vector data; 17 | std::vector has_update; 18 | std::vector updates; 19 | 20 | segment_tree_lazy() {} 21 | 22 | segment_tree_lazy(int _SZ, T _t_identity, U _u_identity, 23 | TAssociativeCombineFunction _TT, UAssociativeCombineFunction _UU, UApplicator _UT) 24 | : SZ(_SZ), t_identity(_t_identity), u_identity(_u_identity), TT(_TT), UU(_UU), UT(_UT) { 25 | data.assign(2 * SZ, t_identity); 26 | has_update.assign(SZ, false); 27 | updates.assign(SZ, u_identity); 28 | } 29 | 30 | template 31 | void assign(Function fn) { 32 | for (int i = 0; i < SZ; i++) 33 | data[SZ + i] = fn(i); 34 | for (int i = SZ - 1; i; i--) 35 | data[i] = TT(data[2 * i], data[2 * i + 1]); 36 | has_update.assign(SZ, false); 37 | updates.assign(SZ, u_identity); 38 | } 39 | 40 | private: 41 | void apply_update(int i, const U &u) { 42 | data[i] = UT(u, data[i]); 43 | if (i < SZ) { 44 | has_update[i] = true; 45 | updates[i] = UU(u, updates[i]); 46 | } 47 | } 48 | 49 | void propagate_ancestor_updates(int i) { 50 | for (int ht = 31 - __builtin_clz(i); ht > 0; ht--) { 51 | int anc = i >> ht; 52 | if (has_update[anc]) { 53 | apply_update(2 * anc, updates[anc]); 54 | apply_update(2 * anc + 1, updates[anc]); 55 | has_update[anc] = false; 56 | updates[anc] = u_identity; 57 | } 58 | } 59 | } 60 | 61 | void recompute_ancestors(int i) { 62 | for (i /= 2; i; i /= 2) 63 | data[i] = UT(updates[i], TT(data[2 * i], data[2 * i + 1])); 64 | } 65 | 66 | void modify_leaf(int i, T v, bool overwrite) { 67 | i += SZ; 68 | propagate_ancestor_updates(i); 69 | data[i] = overwrite ? v : TT(data[i], v); 70 | recompute_ancestors(i); 71 | } 72 | 73 | public: 74 | // Assigns v at index i 75 | void assign(int i, T v) { 76 | modify_leaf(i, v, true); 77 | } 78 | 79 | // Replaces the current value at index i with TT(current value, v) 80 | void combine_and_assign(int i, T v) { 81 | modify_leaf(i, v, false); 82 | } 83 | 84 | // Applies update u to the elements at indices in [first, last) 85 | void apply_update(int first, int last, U u) { 86 | assert(0 <= first && last <= SZ); 87 | first += SZ, last += SZ; 88 | 89 | propagate_ancestor_updates(first); 90 | propagate_ancestor_updates(last - 1); 91 | 92 | for (int i = first, j = last; i < j; i /= 2, j /= 2) { 93 | if (i&1) apply_update(i++, u); 94 | if (j&1) apply_update(--j, u); 95 | } 96 | 97 | recompute_ancestors(first); 98 | recompute_ancestors(last - 1); 99 | } 100 | 101 | // Accumulates the elements at indices in [first, last) 102 | T accumulate(int first, int last) { 103 | assert(0 <= first && last <= SZ); 104 | first += SZ, last += SZ; 105 | 106 | propagate_ancestor_updates(first); 107 | propagate_ancestor_updates(last - 1); 108 | 109 | T left = t_identity, right = t_identity; 110 | for (int i = first, j = last; i < j; i /= 2, j /= 2) { 111 | if (i&1) left = TT(left, data[i++]); 112 | if (j&1) right = TT(data[--j], right); 113 | } 114 | return TT(left, right); 115 | } 116 | 117 | // Returns the current value at index i 118 | T read(int i) { 119 | i += SZ; 120 | propagate_ancestor_updates(i); 121 | return data[i]; 122 | } 123 | }; 124 | --------------------------------------------------------------------------------