├── .gitattributes ├── .gitignore ├── Builds ├── _C++17.sublime-build ├── _C++17_DLOCAL.sublime-build ├── _C++17_Optimized.sublime-build ├── _C++17_Optimized_DLOCAL.sublime-build ├── _C++20.sublime-build ├── _C++20_DLOCAL.sublime-build ├── _C++20_Optimized.sublime-build ├── _C++20_Optimized_DLOCAL.sublime-build ├── _C++23.sublime-build ├── _C++23_DLOCAL.sublime-build ├── _C++23_Optimized.sublime-build ├── _C++23_Optimized_DLOCAL.sublime-build ├── _C++26.sublime-build ├── _C++26_DLOCAL.sublime-build ├── _C++26_Optimized.sublime-build ├── _C++26_Optimized_DLOCAL.sublime-build ├── _C++26_Optimized_Multithreaded.sublime-build ├── _Dot.sublime-build └── _Java.sublime-build ├── C++_completions.sublime-completions ├── Default (Linux).sublime-keymap ├── Default (Windows).sublime-keymap ├── Java_completions.sublime-completions ├── Java_initialize.sublime-snippet ├── Kotlin.sublime-settings ├── Library ├── Abstract_Algebra │ ├── Finite_Field │ │ ├── factorizer_over_finite_field.sublime-snippet │ │ ├── finite_field_char2_small.sublime-snippet │ │ └── irreducibility_finite_field.sublime-snippet │ ├── Lambda_Operations │ │ └── lambda_arithmetic_monoid_action.sublime-snippet │ ├── cosets.sublime-snippet │ ├── division_ring.sublime-snippet │ ├── elliptic_curve.sublime-snippet │ ├── field_of_fraction.sublime-snippet │ ├── find_a_commutative_group_basis.sublime-snippet │ ├── find_the_order_of_all_group_elements.sublime-snippet │ ├── group.sublime-snippet │ ├── group_generator.sublime-snippet │ ├── monoid.sublime-snippet │ ├── nimber_product.sublime-snippet │ ├── quotient_group.sublime-snippet │ ├── ring.sublime-snippet │ ├── test_closedness.sublime-snippet │ ├── test_commutative_group_isomorphism.sublime-snippet │ ├── test_commutative_group_nilpotency.sublime-snippet │ ├── test_direct_product.sublime-snippet │ ├── test_group_axioms.sublime-snippet │ ├── test_group_commutativity.sublime-snippet │ └── test_normal_subgroup.sublime-snippet ├── Combinatorial │ ├── Block_Minmax_Processor │ │ ├── block_minmax_processor.sublime-snippet │ │ └── block_minmax_processor_2d.sublime-snippet │ ├── Edge_Coloring │ │ ├── edge_coloring_bipartite.sublime-snippet │ │ └── edge_coloring_vizing.sublime-snippet │ ├── Flow_Matching_And_Cut │ │ ├── Minimum_Cost_Maximum_Flow │ │ │ ├── minimum_cost_maximum_flow_johnson.sublime-snippet │ │ │ ├── minimum_cost_maximum_flow_push_relabel.sublime-snippet │ │ │ └── minimum_cost_maximum_flow_spfa.sublime-snippet │ │ ├── _Fundamentals │ │ │ ├── flow_network.sublime-snippet │ │ │ ├── flow_network_weighted.sublime-snippet │ │ │ ├── flow_network_with_demand.sublime-snippet │ │ │ └── maximum_bipartite_matching_solver.sublime-snippet │ │ ├── blossom_maximum_unweighted_matching.sublime-snippet │ │ ├── dinic_maximum_flow.sublime-snippet │ │ ├── flow_decomposition.sublime-snippet │ │ ├── global_min_cut.sublime-snippet │ │ ├── gomory_hu.sublime-snippet │ │ ├── hopcroft_karp_algorithm.sublime-snippet │ │ ├── hungarian_weighted_bipartite_matching.sublime-snippet │ │ ├── kuhn_algorithm.sublime-snippet │ │ ├── maximum_antichain.sublime-snippet │ │ ├── maximum_density_subset.sublime-snippet │ │ ├── maximum_weight_matching.sublime-snippet │ │ ├── maximum_weight_matching_short.sublime-snippet │ │ ├── minimum_path_cover.sublime-snippet │ │ ├── network_simplex.sublime-snippet │ │ ├── positive_bipartite_two_sat.sublime-snippet │ │ ├── push_relabel.sublime-snippet │ │ └── spanning_tree_polytope_separation_oracle.sublime-snippet │ ├── Linear_Programming │ │ └── linear_programming_solver_simplex.sublime-snippet │ ├── Longest_Monotone_Subsequence │ │ ├── longest_increasing_bisubsequence.sublime-snippet │ │ ├── longest_monotone_subsequence.sublime-snippet │ │ └── longest_monotone_subsequence_processor.sublime-snippet │ ├── Matroid │ │ ├── matroid.sublime-snippet │ │ ├── matroid_intersection.sublime-snippet │ │ ├── minimum_cost_matroid_intersection_bellman_ford.sublime-snippet │ │ ├── minimum_cost_matroid_intersection_spfa.sublime-snippet │ │ └── rigidity_matroid.sublime-snippet │ ├── Permutation │ │ ├── count_inversions.sublime-snippet │ │ └── permutation.sublime-snippet │ ├── Submodularity │ │ ├── check_antisubmodularity.sublime-snippet │ │ ├── graph_representable_monge_function_optimization.sublime-snippet │ │ └── graph_representable_submodular_function_optimization.sublime-snippet │ ├── Young_Tableau │ │ ├── RSK_inverse_mapping.sublime-snippet │ │ ├── RSK_mapping.sublime-snippet │ │ ├── RSK_mapping_fast.sublime-snippet │ │ ├── count_young_tableaux.sublime-snippet │ │ ├── longest_k_increasing_subsequence_nklogn_nk2.sublime-snippet │ │ └── longest_k_increasing_subsequence_nr.sublime-snippet │ ├── bidirectional_ballot_sequence_count.sublime-snippet │ ├── combinatorics.sublime-snippet │ ├── compute_sum_of_non_intersecting_tuples_of_paths.sublime-snippet │ ├── enumerate_partitions.sublime-snippet │ ├── enumerate_polyominos.sublime-snippet │ └── q_combinatorics.sublime-snippet ├── Continued_Fraction_and_Farey_Sequence │ ├── continued_fraction.sublime-snippet │ └── farey_sequence.sublime-snippet ├── Data_Structure │ ├── Cartesian_Tree │ │ └── cartesian_tree.sublime-snippet │ ├── Cut_Join_Tree │ │ └── cut_join_tree.sublime-snippet │ ├── Data_Structure_Enhancer │ │ ├── data_structure_deletion_enabler_offline.sublime-snippet │ │ ├── data_structure_insertion_enabler_online.sublime-snippet │ │ ├── data_structure_multidimensional_priority_queue_like_deletion_enabler_online.sublime-snippet │ │ ├── data_structure_priority_queue_like_deletion_enabler_online.sublime-snippet │ │ └── data_structure_queue_like_deletion_enabler_online.sublime-snippet │ ├── Disjoint_Set │ │ ├── disjoint_set.sublime-snippet │ │ ├── disjoint_set_2d.sublime-snippet │ │ ├── disjoint_set_rollback.sublime-snippet │ │ └── persistent_disjoint_set.sublime-snippet │ ├── Disjoint_Sparse_Table │ │ └── disjoint_sparse_table.sublime-snippet │ ├── Distinct_Value_Query_solver │ │ ├── distinct_value_count_query_solve_online_cubic_root.sublime-snippet │ │ ├── distinct_value_query_solver_offline.sublime-snippet │ │ └── distinct_value_query_solver_online.sublime-snippet │ ├── Fenwick_Tree │ │ ├── fenwick_tree.sublime-snippet │ │ ├── fenwick_tree_2d_sparse_sum.sublime-snippet │ │ ├── fenwick_tree_2d_sum.sublime-snippet │ │ ├── fenwick_tree_3d_sum.sublime-snippet │ │ ├── range_add_query_sum_solver.sublime-snippet │ │ ├── range_add_query_sum_solver_2d.sublime-snippet │ │ └── range_xor_query_xor_solver_2d.sublime-snippet │ ├── Integral_Set │ │ ├── integral_map.sublime-snippet │ │ └── integral_multiset.sublime-snippet │ ├── Interval_Processor │ │ └── colorful_interval_set.sublime-snippet │ ├── Kd_Tree │ │ └── kdtree_minmax.sublime-snippet │ ├── Line_Container │ │ ├── kinetic_tournament.sublime-snippet │ │ ├── li_chao_tree.sublime-snippet │ │ ├── li_chao_tree_fixed_query.sublime-snippet │ │ ├── li_chao_tree_order_statistic.sublime-snippet │ │ ├── line_container.sublime-snippet │ │ └── sorted_line_container.sublime-snippet │ ├── Link_Cut_Trees │ │ └── link_cut_trees.sublime-snippet │ ├── Multidimentional_Array │ │ ├── kdarray.sublime-snippet │ │ └── kdsum.sublime-snippet │ ├── PQ_Tree │ │ └── pq_tree.sublime-snippet │ ├── Persistent_Array │ │ └── persistent_array.sublime-snippet │ ├── Potential_Tracker │ │ └── potential_tracker.sublime-snippet │ ├── Priority_Queue │ │ ├── partially_retroactive_priority_queue.sublime-snippet │ │ └── priority_queue_with_update.sublime-snippet │ ├── Range_Inversion_Query_Solver │ │ └── range_inversion_query_solver_offline.sublime-snippet │ ├── Range_Mex_Query_Solver │ │ ├── range_mex_query_solver_offline.sublime-snippet │ │ └── range_mex_query_solver_online.sublime-snippet │ ├── Range_Mode_Query │ │ └── range_mode_query_solver_online.sublime-snippet │ ├── Segment_Tree │ │ ├── mergesort_tree.sublime-snippet │ │ ├── mergesort_tree_point_update.sublime-snippet │ │ ├── segment_tree.sublime-snippet │ │ ├── segment_tree_2d.sublime-snippet │ │ ├── segment_tree_2d_sparse.sublime-snippet │ │ ├── segment_tree_3d.sublime-snippet │ │ ├── segment_tree_dynamic.sublime-snippet │ │ ├── segment_tree_persistent.sublime-snippet │ │ └── segment_tree_wide.sublime-snippet │ ├── Sequence_Update_Processor │ │ ├── arithmetic_sequence_update_processor.sublime-snippet │ │ └── polynomial_sequence_update_processor.sublime-snippet │ ├── Sliding_Window_Aggregation │ │ ├── swag_deque.sublime-snippet │ │ └── swag_queue.sublime-snippet │ ├── Sparse_Table │ │ ├── range_minmax_query_solver.sublime-snippet │ │ ├── sparse_table.sublime-snippet │ │ ├── sparse_table_2d.sublime-snippet │ │ └── sparse_table_2d_square.sublime-snippet │ ├── Sqrt_Decomposition │ │ ├── mo_2d.sublime-snippet │ │ ├── mo_2d_hilbert_curve_ordering.sublime-snippet │ │ ├── mo_2d_rectilinear_spanning_tree_ordering.sublime-snippet │ │ ├── mo_2d_rollback.sublime-snippet │ │ ├── mo_3d.sublime-snippet │ │ ├── mo_sweepline.sublime-snippet │ │ ├── sqrt_decomposition_heavy_point_update_light_range_query_commutative_group.sublime-snippet │ │ └── sqrt_decomposition_light_point_update_heavy_range_query_commutative_monoid.sublime-snippet │ ├── Subinterval_Sum_Processor │ │ └── subinterval_sum_processor.sublime-snippet │ ├── Top_Tree │ │ └── static_top_tree.sublime-snippet │ ├── Treap │ │ └── treap.sublime-snippet │ ├── Trie │ │ └── binary_trie_dynamic.sublime-snippet │ ├── Unital_Sorter │ │ └── unital_sorter.sublime-snippet │ ├── Value_Range_Query_Solver │ │ └── value_range_query_solver_online_sqrt.sublime-snippet │ ├── Value_Trackers │ │ ├── range_choose_sum_tracker.sublime-snippet │ │ └── sorted_range_sum_tracker.sublime-snippet │ └── Wavelet_Structures │ │ ├── wavelet_matrix.sublime-snippet │ │ └── wavelet_tree.sublime-snippet ├── Dynamic_Programming │ ├── count_rectangles_within_grid.sublime-snippet │ ├── divide_and_conquer_optimization.sublime-snippet │ ├── knuth_optimization.sublime-snippet │ ├── lagrange_optimization.sublime-snippet │ ├── monotone_queue_optimization.sublime-snippet │ ├── smawk.sublime-snippet │ ├── span_with_subarray.sublime-snippet │ └── subset_sum.sublime-snippet ├── Geometry │ ├── Circle │ │ ├── circle.sublime-snippet │ │ ├── circle_common_tangents.sublime-snippet │ │ ├── circle_intersection.sublime-snippet │ │ ├── circle_polygon_intersection.sublime-snippet │ │ ├── find_circle_point_inclusion_relations.sublime-snippet │ │ ├── minimum_enclosing_circle.sublime-snippet │ │ └── radical_axis.sublime-snippet │ ├── Convex_Polygon │ │ ├── convex_polygon.sublime-snippet │ │ ├── convex_polygon_diameter.sublime-snippet │ │ ├── convex_polygon_extreme_point.sublime-snippet │ │ ├── convex_polygon_locate.sublime-snippet │ │ ├── convex_polyhedra.sublime-snippet │ │ ├── count_convex_polygon.sublime-snippet │ │ ├── find_convex_polygon_point_inclusion_relations.sublime-snippet │ │ └── half_planes_intersection.sublime-snippet │ ├── Decomposition │ │ ├── delaunay_triangulation.sublime-snippet │ │ ├── quad_edge.sublime-snippet │ │ ├── trapzoidal_decomposition.sublime-snippet │ │ └── triangular_decomposition.sublime-snippet │ ├── Line │ │ ├── find_closed_lines_intersections.sublime-snippet │ │ ├── line.sublime-snippet │ │ ├── line3.sublime-snippet │ │ ├── line_intersection.sublime-snippet │ │ └── line_to_line_distance.sublime-snippet │ ├── Norm │ │ ├── find_a_closest_pair.sublime-snippet │ │ ├── find_a_furthest_pair_L1.sublime-snippet │ │ ├── find_a_furthest_pair_L2.sublime-snippet │ │ ├── find_a_furthest_pair_Linf.sublime-snippet │ │ └── rectilinear_minimum_spanning_tree.sublime-snippet │ ├── Point │ │ ├── point.sublime-snippet │ │ └── point3.sublime-snippet │ ├── Polygon │ │ ├── point_in_polygon.sublime-snippet │ │ ├── polygon_cut.sublime-snippet │ │ └── segment_in_polygon.sublime-snippet │ ├── Sweepline │ │ ├── radial_sweepline_grouper.sublime-snippet │ │ └── radial_sweepline_sorter.sublime-snippet │ └── triangle_centers.sublime-snippet ├── Graph_Theory │ ├── Chromatic_Polynomial │ │ └── chromatic_polynomial_functional_graph.sublime-snippet │ ├── Clique │ │ ├── count_cliques.sublime-snippet │ │ ├── count_cliques_weighted.sublime-snippet │ │ ├── enumerate_maximal_cliques.sublime-snippet │ │ ├── enumerate_maximal_cliques_large.sublime-snippet │ │ ├── find_a_maximum_clique.sublime-snippet │ │ └── find_a_maximum_clique_large.sublime-snippet │ ├── Connectivity │ │ ├── biconnected_components.sublime-snippet │ │ ├── bipolar_orientation.sublime-snippet │ │ ├── ear_decomposition.sublime-snippet │ │ ├── recover_two_sat.sublime-snippet │ │ ├── strong_augmentation.sublime-snippet │ │ ├── strongly_connected_components.sublime-snippet │ │ ├── strongly_connected_components_offline_incremental.sublime-snippet │ │ └── two_sat_solver.sublime-snippet │ ├── DFS_Based │ │ ├── find_dominators.sublime-snippet │ │ ├── greedy_coloring.sublime-snippet │ │ ├── reachable_even_cycle_finder.sublime-snippet │ │ └── topological_sorter.sublime-snippet │ ├── Euler_Walk │ │ └── euler_walk.sublime-snippet │ ├── Forest_Algorithms │ │ ├── almost_uniformly_partitionable.sublime-snippet │ │ ├── binary_lifting.sublime-snippet │ │ ├── centroid_decomposition.sublime-snippet │ │ ├── centroid_processor.sublime-snippet │ │ ├── compressed_tree.sublime-snippet │ │ ├── forest_path_query_solver_commutative_group.sublime-snippet │ │ ├── forest_query_solver.sublime-snippet │ │ ├── heavy_light_decomposition.sublime-snippet │ │ ├── lca_solver.sublime-snippet │ │ ├── lca_solver_offline.sublime-snippet │ │ ├── precalc_directional_heights.sublime-snippet │ │ ├── prufer_code.sublime-snippet │ │ ├── rerooter.sublime-snippet │ │ ├── shallowest_decomposition.sublime-snippet │ │ ├── skew_binary_lifting.sublime-snippet │ │ ├── small_to_large_on_forest.sublime-snippet │ │ ├── static_path_minmax_processor.sublime-snippet │ │ ├── tree_diameter.sublime-snippet │ │ ├── tree_hasher.sublime-snippet │ │ └── weighted_binary_lifting.sublime-snippet │ ├── Graph_Decomposition │ │ └── decompose_into_paths_of_length_2.sublime-snippet │ ├── Graph_Readers │ │ ├── raw_read_digraph.sublime-snippet │ │ ├── raw_read_graph.sublime-snippet │ │ ├── raw_read_tree.sublime-snippet │ │ ├── raw_read_wdigraph.sublime-snippet │ │ ├── raw_read_wgraph.sublime-snippet │ │ ├── raw_read_wtree.sublime-snippet │ │ ├── read_digraph.sublime-snippet │ │ ├── read_graph.sublime-snippet │ │ ├── read_tree.sublime-snippet │ │ ├── read_wdigraph.sublime-snippet │ │ ├── read_wgraph.sublime-snippet │ │ └── read_wtree.sublime-snippet │ ├── Shortest_Path_Algorithms │ │ ├── Bellman_Ford │ │ │ └── bellman_ford.sublime-snippet │ │ ├── Dial │ │ │ └── dial.sublime-snippet │ │ ├── Dijkstra │ │ │ ├── dijkstra.sublime-snippet │ │ │ └── dijkstra_dense.sublime-snippet │ │ ├── Floyd_Warshall │ │ │ └── floyd_warshall.sublime-snippet │ │ ├── Minimum_Mean_Weight_Cycle │ │ │ └── minimum_mean_weight_cycle.sublime-snippet │ │ ├── Shortest_Path_Faster_Algorithm │ │ │ └── spfa.sublime-snippet │ │ └── successive_shortest_path_solver.sublime-snippet │ ├── Spanning_Forest_Algorithms │ │ ├── bfs_forest.sublime-snippet │ │ ├── complement_spanning_forest.sublime-snippet │ │ ├── count_spanning_forest.sublime-snippet │ │ ├── dfs_forest.sublime-snippet │ │ ├── lexicographical_bfs_forest.sublime-snippet │ │ ├── minimum_spanning_arborescence.sublime-snippet │ │ ├── minimum_spanning_forest.sublime-snippet │ │ └── minimum_steiner_tree.sublime-snippet │ ├── Special_Graphs │ │ ├── admissible_graph.sublime-snippet │ │ ├── find_maximal_cycles_in_tournament_graphs.sublime-snippet │ │ ├── functional_graph_processor.sublime-snippet │ │ ├── maximum_independent_set_on_cactus.sublime-snippet │ │ ├── recognize_chordal_graphs.sublime-snippet │ │ └── recognize_cographs.sublime-snippet │ ├── Sqrt_Trick │ │ ├── count_4_cycles.sublime-snippet │ │ ├── find_3_cycles.sublime-snippet │ │ └── find_4_cycles.sublime-snippet │ ├── Tree_Decomposition │ │ ├── is_tree_decomposition_of.sublime-snippet │ │ ├── maximum_independent_set_on_tree_decomposition.sublime-snippet │ │ ├── tree_decomposition_cactus_halin_graph.sublime-snippet │ │ ├── tree_decomposition_chordal_graph.sublime-snippet │ │ └── tree_decomposition_halin_graph.sublime-snippet │ ├── edge_path_into_vertex_path.sublime-snippet │ ├── find_all_cycle_masks.sublime-snippet │ └── graph.sublime-snippet ├── Grid │ ├── direction_vectors.sublime-snippet │ ├── grid_bfs_forest.sublime-snippet │ └── grid_dijkstra.sublime-snippet ├── Heuristic_Algorithms │ ├── hamiltonian_path_of_random_graph.sublime-snippet │ └── simulated_annealing.sublime-snippet ├── Initialize │ ├── __initialize.sublime-snippet │ ├── __mhc_init.sublime-snippet │ ├── __mhc_multithread_init.sublime-snippet │ ├── __scpc_init.sublime-snippet │ ├── __tc_init.sublime-snippet │ ├── __tc_init_python.sublime-snippet │ └── __testlib_init.sublime-snippet ├── Linear_Algebra │ ├── Linear_Equation_Solver │ │ ├── linear_equation_solver.sublime-snippet │ │ ├── linear_equation_solver_GF2.sublime-snippet │ │ └── pick_subset_with_given_xor.sublime-snippet │ ├── Linear_Recurrence_Solver │ │ ├── fibonacci.sublime-snippet │ │ ├── linear_recurrence_solver.sublime-snippet │ │ ├── linear_recurrence_solver_bostan_mori.sublime-snippet │ │ └── linear_recurrence_solver_modular_exponentiation.sublime-snippet │ └── Matrix │ │ ├── characteristic_polynomial.sublime-snippet │ │ ├── characteristic_polynomial_commutative_ring.sublime-snippet │ │ ├── determinant_commutative_ring.sublime-snippet │ │ ├── determinant_linear_polynomial.sublime-snippet │ │ ├── determinant_polynomial.sublime-snippet │ │ ├── matrix.sublime-snippet │ │ ├── matrix_AND_OR_base.sublime-snippet │ │ ├── matrix_OR_AND.sublime-snippet │ │ ├── matrix_Z2.sublime-snippet │ │ ├── matrix_fixed.sublime-snippet │ │ ├── matrix_inverse_tracker.sublime-snippet │ │ ├── sparse_determinant.sublime-snippet │ │ ├── sparse_minimal_polynomial.sublime-snippet │ │ ├── tridiagonal_matrix_determinant.sublime-snippet │ │ └── tridiagonal_matrix_equation_solver.sublime-snippet ├── Miscellaneous │ ├── bigint.sublime-snippet │ ├── bitset64.sublime-snippet │ ├── bitset_augmentation.sublime-snippet │ ├── de_bruijn_bit_magic.sublime-snippet │ ├── fastio.sublime-snippet │ ├── floored_root.sublime-snippet │ ├── hilbert_curve_2d.sublime-snippet │ ├── int128_augmentation.sublime-snippet │ ├── logging_allocator.sublime-snippet │ ├── mex.sublime-snippet │ ├── next_bit_permutation.sublime-snippet │ ├── pbds.sublime-snippet │ ├── png_parser.sublime-snippet │ ├── random.sublime-snippet │ ├── state_evolver.sublime-snippet │ ├── timer.sublime-snippet │ ├── trygub_number.sublime-snippet │ ├── type_name.sublime-snippet │ ├── value_compressor.sublime-snippet │ └── y_combinator.sublime-snippet ├── Network_Communication │ └── network_communication_manager.sublime-snippet ├── Number_Theory │ ├── Chinese_Remainder_Theorem │ │ ├── chinese_remainder_theorem_coprime_fixed_width.sublime-snippet │ │ └── chinese_remainder_theorem_linear.sublime-snippet │ ├── Integer_Decomposition │ │ ├── solve_fermat_three_triangle.sublime-snippet │ │ ├── solve_fermat_two_square.sublime-snippet │ │ ├── solve_lagrange_four_square.sublime-snippet │ │ └── solve_legendre_three_square.sublime-snippet │ ├── Modular │ │ ├── mod_sqrt.sublime-snippet │ │ ├── modular_fixed.sublime-snippet │ │ ├── modular_unfixed.sublime-snippet │ │ ├── montgomery_modular_fixed.sublime-snippet │ │ └── montgomery_modular_unfixed.sublime-snippet │ ├── Multiplicative_Prefix_Sum │ │ ├── count_primes.sublime-snippet │ │ ├── meissel_lehmer.sublime-snippet │ │ ├── min25_sieve.sublime-snippet │ │ ├── min25_sieve_wrong.sublime-snippet │ │ └── xudyh_sieve.sublime-snippet │ ├── barret_reduction.sublime-snippet │ ├── diophantine.sublime-snippet │ ├── dirichlet_convolution_formulae.sublime-snippet │ ├── divisor_count_function_prefix_sum.sublime-snippet │ ├── extended_euclidean.sublime-snippet │ ├── factorize.sublime-snippet │ ├── find_first_residue.sublime-snippet │ ├── floor_sum.sublime-snippet │ ├── floor_sum_weighted.sublime-snippet │ ├── for_each_divisor.sublime-snippet │ ├── harmonic_loop.sublime-snippet │ ├── inverse_linear_congruential_generator.sublime-snippet │ ├── jacobi_symbol.sublime-snippet │ ├── number_theory.sublime-snippet │ └── pollard_rho.sublime-snippet ├── Numeric │ ├── binary_geometric_sum.sublime-snippet │ ├── binary_geometric_sum_general.sublime-snippet │ ├── binary_power.sublime-snippet │ ├── binary_power_general.sublime-snippet │ ├── binary_string.sublime-snippet │ ├── continuous_binary_search.sublime-snippet │ ├── counting_iterator.sublime-snippet │ ├── discrete_golden_section_search.sublime-snippet │ ├── discrete_ternary_search.sublime-snippet │ ├── double_parallel_binary_search.sublime-snippet │ ├── find_prefix_xor_order.sublime-snippet │ ├── fractional_search.sublime-snippet │ ├── golden_section_search.sublime-snippet │ ├── parallel_binary_search.sublime-snippet │ └── solve_cubic_equation.sublime-snippet ├── Power_Series │ ├── Bell_Number │ │ └── bell_number.sublime-snippet │ ├── Convolutions │ │ └── convolve_subset.sublime-snippet │ ├── Power_Sum │ │ ├── bernoulli_number.sublime-snippet │ │ ├── power_sum.sublime-snippet │ │ └── power_sum_prefix_evaluation.sublime-snippet │ ├── Set_Power_Series │ │ ├── exponential_set_power_series.sublime-snippet │ │ └── logarithm_set_power_series.sublime-snippet │ ├── Transformations │ │ ├── chirp_z_transform.sublime-snippet │ │ ├── fast_fourier_transform.sublime-snippet │ │ ├── fast_fourier_transform_multidimensional.sublime-snippet │ │ └── number_theoric_transform.sublime-snippet │ ├── chebyshev_eval.sublime-snippet │ ├── interpolate_range_naive.sublime-snippet │ ├── polynomial_shift_sampling.sublime-snippet │ ├── power_series.sublime-snippet │ ├── power_series_composition.sublime-snippet │ ├── power_series_compositional_inverse.sublime-snippet │ ├── power_series_naive.sublime-snippet │ ├── power_series_online.sublime-snippet │ ├── power_series_sqrt.sublime-snippet │ ├── rational_polynomial_single_term_extraction.sublime-snippet │ ├── reduce_quadratic_GF2_polynomial.sublime-snippet │ ├── sequential_polynomial.sublime-snippet │ ├── subproduct_tree.sublime-snippet │ ├── taylor_shift.sublime-snippet │ └── touchard_polynomial.sublime-snippet ├── Random_Generators │ ├── generate_chordal_graph.sublime-snippet │ ├── generate_colinear_points.sublime-snippet │ ├── generate_edge_cactus.sublime-snippet │ ├── generate_graph.sublime-snippet │ ├── generate_parallel_planar_graph.sublime-snippet │ ├── generate_planar_graph.sublime-snippet │ ├── generate_simple_graph.sublime-snippet │ ├── generate_simple_polygon.sublime-snippet │ ├── generate_simply_connected_bipartite_graph.sublime-snippet │ ├── generate_simply_connected_graph.sublime-snippet │ └── generate_tree.sublime-snippet ├── String │ ├── Aho_Corasic_Automaton │ │ ├── aho_corasic_automaton_fixed.sublime-snippet │ │ └── aho_corasic_automaton_unfixed.sublime-snippet │ ├── Autocorrelation │ │ ├── autocorrelation_free_variable_count.sublime-snippet │ │ ├── autocorrelation_membership_test.sublime-snippet │ │ ├── autocorrelation_to_string.sublime-snippet │ │ ├── enumerate_autocorrelations.sublime-snippet │ │ └── string_to_autocorrelation.sublime-snippet │ ├── Burrows_Wheeler_Transform │ │ └── burrows_wheeler_transform.sublime-snippet │ ├── Composite_String_Comparator │ │ └── composite_string_comparator.sublime-snippet │ ├── Hash │ │ ├── hash.sublime-snippet │ │ ├── hash_bidirectional.sublime-snippet │ │ └── substring_hasher.sublime-snippet │ ├── Longest_Common_Subsequence │ │ ├── circular_longest_common_subsequence.sublime-snippet │ │ ├── longest_common_subsequence.sublime-snippet │ │ └── longest_common_subsequence_lengths.sublime-snippet │ ├── Lyndon │ │ ├── lyndon_factorization.sublime-snippet │ │ └── minimal_rotation.sublime-snippet │ ├── Main_Lorentz │ │ └── main_lorentz.sublime-snippet │ ├── Manacher │ │ └── manacher.sublime-snippet │ ├── Matching_With_Wildcards │ │ ├── matching_with_wildcards.sublime-snippet │ │ └── matching_with_wildcards_randomized.sublime-snippet │ ├── Palindrome_Automaton │ │ └── palindrome_automaton.sublime-snippet │ ├── String_Processor │ │ └── string_processor.sublime-snippet │ ├── Suffix_Array │ │ ├── suffix_array.sublime-snippet │ │ └── suffix_array_slow.sublime-snippet │ ├── Suffix_Automaton │ │ └── suffix_automaton.sublime-snippet │ ├── Suffix_Tree │ │ └── suffix_tree.sublime-snippet │ ├── Trie │ │ ├── binary_trie.sublime-snippet │ │ └── trie.sublime-snippet │ └── Utility │ │ ├── count_common_substrings.sublime-snippet │ │ ├── count_distinct_substrings.sublime-snippet │ │ ├── distinct_substring_count_query_solver_offline.sublime-snippet │ │ └── longest_common_substring.sublime-snippet ├── Succinct_Structures │ └── succinct_dictionary.sublime-snippet └── _TEST │ ├── _TEST_LCT │ ├── _TEST_Commutative_Op │ │ ├── _TEST_LCT │ │ │ ├── a.cpp │ │ │ ├── b.cpp │ │ │ └── gen.cpp │ │ ├── _TEST_PQPUSQSU_LCT │ │ │ ├── a.cpp │ │ │ ├── b.cpp │ │ │ └── gen.cpp │ │ ├── _TEST_PQPUSQ_LCT │ │ │ ├── a.cpp │ │ │ ├── b.cpp │ │ │ └── gen.cpp │ │ ├── _TEST_PQPUSU_LCT │ │ │ ├── a.cpp │ │ │ ├── b.cpp │ │ │ └── gen.cpp │ │ ├── _TEST_PQPU_LCT │ │ │ ├── a.cpp │ │ │ ├── b.cpp │ │ │ └── gen.cpp │ │ ├── _TEST_PQSQSU_LCT │ │ │ ├── a.cpp │ │ │ ├── b.cpp │ │ │ └── gen.cpp │ │ ├── _TEST_PQSQ_LCT │ │ │ ├── a.cpp │ │ │ ├── b.cpp │ │ │ └── gen.cpp │ │ ├── _TEST_PQSU_LCT │ │ │ ├── a.cpp │ │ │ ├── b.cpp │ │ │ └── gen.cpp │ │ ├── _TEST_PQ_LCT │ │ │ ├── a.cpp │ │ │ ├── b.cpp │ │ │ └── gen.cpp │ │ ├── _TEST_PUSU_LCT │ │ │ ├── a.cpp │ │ │ ├── b.cpp │ │ │ └── gen.cpp │ │ ├── _TEST_PU_LCT │ │ │ ├── a.cpp │ │ │ ├── b.cpp │ │ │ └── gen.cpp │ │ ├── _TEST_SQSU_LCT │ │ │ ├── a.cpp │ │ │ ├── b.cpp │ │ │ └── gen.cpp │ │ ├── _TEST_SQ_LCT │ │ │ ├── a.cpp │ │ │ ├── b.cpp │ │ │ └── gen.cpp │ │ └── _TEST_SU_LCT │ │ │ ├── a.cpp │ │ │ ├── b.cpp │ │ │ └── gen.cpp │ └── _TEST_Non_Commutative_Op │ │ ├── _TEST_PQPUSU_LCT │ │ ├── a.cpp │ │ ├── b.cpp │ │ └── gen.cpp │ │ ├── _TEST_PQPU_LCT │ │ ├── a.cpp │ │ ├── b.cpp │ │ └── gen.cpp │ │ ├── _TEST_PQSU_LCT │ │ ├── a.cpp │ │ ├── b.cpp │ │ └── gen.cpp │ │ └── _TEST_PQ_LCT │ │ ├── a.cpp │ │ ├── b.cpp │ │ └── gen.cpp │ ├── _TEST_bigint │ ├── a.cpp │ ├── a.py │ └── gen.cpp │ ├── _TEST_colorful_interval_set │ ├── a.cpp │ └── gen.cpp │ ├── _TEST_graph_representable_submodular_function_optimization │ ├── b.cpp │ └── gen.cpp │ ├── _TEST_segment_tree │ └── _TEST_segment_tree_persistent │ │ ├── _TEST_Q │ │ ├── a.cpp │ │ ├── b.cpp │ │ └── gen.cpp │ │ ├── _TEST_QU │ │ ├── a.cpp │ │ ├── b.cpp │ │ └── gen.cpp │ │ └── _TEST_U │ │ ├── a.cpp │ │ ├── b.cpp │ │ └── gen.cpp │ └── _TEST_treap │ ├── _TEST_F_Treap │ ├── a.cpp │ ├── b.cpp │ └── gen.cpp │ ├── _TEST_UQF_treap │ ├── a.cpp │ ├── b.cpp │ └── gen.cpp │ └── _TEST_UcQF_treap │ ├── a.cpp │ ├── b.cpp │ └── gen.cpp ├── MarkdownPreview.sublime-settings ├── Package Control.sublime-settings ├── Preferences.sublime-settings ├── Python.sublime-settings ├── Python_completions.sublime-completions ├── README.md └── SublimePrint.sublime-settings /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | ignore.* 3 | unfinished.* -------------------------------------------------------------------------------- /Builds/_C++17.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "g++", "-std=c++17", "-Wno-unused-result", "-fconcepts", "-g", "-fsanitize=address,undefined", "./${file_name}", "-o", "${file_base_name}"], 4 | "working_dir":"$file_path", 5 | "selector":"source.cpp" 6 | }, 7 | "linux":{ 8 | "cmd": ["g++", "-std=c++17", "-Wno-unused-result", "-fconcepts", "-g", "-fsanitize=address,undefined", "./${file_name}", "-o", "${file_base_name}"], 9 | "working_dir":"$file_path", 10 | "selector":"source.cpp" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Builds/_C++17_DLOCAL.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "g++", "-Winvalid-pch", "-std=c++17", "-DLOCAL", "-I/home/aeren-wsl/Precompiled_Headers", "-Wno-unused-result", "-fconcepts", "-g", "-fsanitize=address,undefined", "./${file_name}", "-o", "${file_base_name}"], 4 | "working_dir":"$file_path", 5 | "selector":"source.cpp" 6 | }, 7 | "linux":{ 8 | "cmd": ["g++", "-Winvalid-pch", "-std=c++17", "-DLOCAL", "-I/home/aeren-wsl/Precompiled_Headers", "-Wno-unused-result", "-fconcepts", "-g", "-fsanitize=address,undefined", "./${file_name}", "-o", "${file_base_name}"], 9 | "working_dir":"$file_path", 10 | "selector":"source.cpp" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Builds/_C++17_Optimized.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "g++", "-std=c++17", "-Wno-unused-result", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 4 | "working_dir":"$file_path", 5 | "selector":"source.cpp" 6 | }, 7 | "linux":{ 8 | "cmd": ["g++", "-std=c++17", "-Wno-unused-result", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 9 | "working_dir":"$file_path", 10 | "selector":"source.cpp" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Builds/_C++17_Optimized_DLOCAL.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "g++", "-std=c++17", "-DLOCAL", "-Wno-unused-result", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 4 | "working_dir":"$file_path", 5 | "selector":"source.cpp", 6 | }, 7 | "linux":{ 8 | "cmd": ["g++", "-std=c++17", "-DLOCAL", "-Wno-unused-result", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 9 | "working_dir":"$file_path", 10 | "selector":"source.cpp", 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Builds/_C++20.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "g++", "-std=c++20", "-Wno-unused-result", "-fconcepts", "-g", "-fsanitize=address,undefined", "./${file_name}", "-o", "${file_base_name}"], 4 | "working_dir":"$file_path", 5 | "selector":"source.cpp" 6 | }, 7 | "linux":{ 8 | "cmd": ["g++", "-std=c++20", "-Wno-unused-result", "-fconcepts", "-g", "-fsanitize=address,undefined", "./${file_name}", "-o", "${file_base_name}"], 9 | "working_dir":"$file_path", 10 | "selector":"source.cpp" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Builds/_C++20_DLOCAL.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "g++", "-Winvalid-pch", "-std=c++20", "-DLOCAL", "-I/home/aeren-wsl/Precompiled_Headers", "-Wno-unused-result", "-fconcepts", "-g", "-fsanitize=address,undefined", "./${file_name}", "-o", "${file_base_name}"], 4 | "working_dir":"$file_path", 5 | "selector":"source.cpp" 6 | }, 7 | "linux":{ 8 | "cmd": ["g++", "-Winvalid-pch", "-std=c++20", "-DLOCAL", "-I/home/aeren-wsl/Precompiled_Headers", "-Wno-unused-result", "-fconcepts", "-g", "-fsanitize=address,undefined", "./${file_name}", "-o", "${file_base_name}"], 9 | "working_dir":"$file_path", 10 | "selector":"source.cpp" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Builds/_C++20_Optimized.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "g++", "-std=c++20", "-Wno-unused-result", "-Wno-free-nonheap-object", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 4 | "working_dir":"$file_path", 5 | "selector":"source.cpp" 6 | }, 7 | "linux":{ 8 | "cmd": ["g++", "-std=c++20", "-Wno-unused-result", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 9 | "working_dir":"$file_path", 10 | "selector":"source.cpp" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Builds/_C++20_Optimized_DLOCAL.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "g++", "-std=c++20", "-DLOCAL", "-Wno-unused-result", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 4 | "working_dir":"$file_path", 5 | "selector":"source.cpp", 6 | }, 7 | "linux":{ 8 | "cmd": ["g++", "-std=c++20", "-DLOCAL", "-Wno-unused-result", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 9 | "working_dir":"$file_path", 10 | "selector":"source.cpp", 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Builds/_C++23.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "g++", "-std=c++23", "-Wno-unused-result", "-fconcepts", "-g", "-fsanitize=address,undefined", "./${file_name}", "-o", "${file_base_name}"], 4 | "working_dir":"$file_path", 5 | "selector":"source.cpp" 6 | }, 7 | "linux":{ 8 | "cmd": ["g++", "-std=c++23", "-Wno-unused-result", "-fconcepts", "-g", "-fsanitize=address,undefined", "./${file_name}", "-o", "${file_base_name}"], 9 | "working_dir":"$file_path", 10 | "selector":"source.cpp" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Builds/_C++23_DLOCAL.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "g++", "-Winvalid-pch", "-std=c++23", "-DLOCAL", "-I/home/aeren-wsl/Precompiled_Headers", "-Wno-unused-result", "-fconcepts", "-g", "-fsanitize=address,undefined", "./${file_name}", "-o", "${file_base_name}"], 4 | "working_dir":"$file_path", 5 | "selector":"source.cpp" 6 | }, 7 | "linux":{ 8 | "cmd": ["g++", "-Winvalid-pch", "-std=c++23", "-DLOCAL", "-I/home/aeren-wsl/Precompiled_Headers", "-Wno-unused-result", "-fconcepts", "-g", "-fsanitize=address,undefined", "./${file_name}", "-o", "${file_base_name}"], 9 | "working_dir":"$file_path", 10 | "selector":"source.cpp" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Builds/_C++23_Optimized.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "g++", "-std=c++23", "-Wno-unused-result", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 4 | "working_dir":"$file_path", 5 | "selector":"source.cpp" 6 | }, 7 | "linux":{ 8 | "cmd": ["g++", "-std=c++23", "-Wno-unused-result", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 9 | "working_dir":"$file_path", 10 | "selector":"source.cpp" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Builds/_C++23_Optimized_DLOCAL.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "g++", "-std=c++23", "-DLOCAL", "-Wno-unused-result", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 4 | "working_dir":"$file_path", 5 | "selector":"source.cpp", 6 | }, 7 | "linux":{ 8 | "cmd": ["g++", "-std=c++23", "-DLOCAL", "-Wno-unused-result", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 9 | "working_dir":"$file_path", 10 | "selector":"source.cpp", 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Builds/_C++26.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "g++", "-std=c++26", "-Wno-unused-result", "-fconcepts", "-g", "-fsanitize=address,undefined", "./${file_name}", "-o", "${file_base_name}"], 4 | "working_dir":"$file_path", 5 | "selector":"source.cpp" 6 | }, 7 | "linux":{ 8 | "cmd": ["g++", "-std=c++26", "-Wno-unused-result", "-fconcepts", "-g", "-fsanitize=address,undefined", "./${file_name}", "-o", "${file_base_name}"], 9 | "working_dir":"$file_path", 10 | "selector":"source.cpp" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Builds/_C++26_DLOCAL.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "g++", "-Winvalid-pch", "-std=c++26", "-DLOCAL", "-I/home/aeren-wsl/Precompiled_Headers", "-Wno-unused-result", "-fconcepts", "-g", "-fsanitize=address,undefined", "./${file_name}", "-o", "${file_base_name}"], 4 | "working_dir":"$file_path", 5 | "selector":"source.cpp" 6 | }, 7 | "linux":{ 8 | "cmd": ["g++", "-Winvalid-pch", "-std=c++26", "-DLOCAL", "-I/home/aeren-wsl/Precompiled_Headers", "-Wno-unused-result", "-fconcepts", "-g", "-fsanitize=address,undefined", "./${file_name}", "-o", "${file_base_name}"], 9 | "working_dir":"$file_path", 10 | "selector":"source.cpp" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Builds/_C++26_Optimized.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "g++", "-std=c++26", "-Wno-unused-result", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 4 | "working_dir":"$file_path", 5 | "selector":"source.cpp" 6 | }, 7 | "linux":{ 8 | "cmd": ["g++", "-std=c++26", "-Wno-unused-result", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 9 | "working_dir":"$file_path", 10 | "selector":"source.cpp" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Builds/_C++26_Optimized_DLOCAL.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "g++", "-std=c++26", "-DLOCAL", "-Wno-unused-result", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 4 | "working_dir":"$file_path", 5 | "selector":"source.cpp", 6 | }, 7 | "linux":{ 8 | "cmd": ["g++", "-std=c++26", "-DLOCAL", "-Wno-unused-result", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 9 | "working_dir":"$file_path", 10 | "selector":"source.cpp", 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Builds/_C++26_Optimized_Multithreaded.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "g++", "-std=c++26", "-pthread", "-Wno-unused-result", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 4 | "working_dir":"$file_path", 5 | "selector":"source.cpp" 6 | }, 7 | "linux":{ 8 | "cmd": ["g++", "-std=c++26", "-pthread", "-Wno-unused-result", "-fconcepts", "-O2", "./${file_name}", "-o", "${file_base_name}"], 9 | "working_dir":"$file_path", 10 | "selector":"source.cpp" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Builds/_Dot.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "cmd": ["wsl.exe", "dot", "-Tpng", "${file_name}", "-o", "${file_base_name}.png"], 3 | "working_dir":"$file_path", 4 | "selector":"source.gv, source.dot" 5 | } -------------------------------------------------------------------------------- /Builds/_Java.sublime-build: -------------------------------------------------------------------------------- 1 | { 2 | "windows":{ 3 | "cmd": ["wsl.exe", "javac", "./${file_name}"], 4 | "selector": "source.java" 5 | }, 6 | "linux":{ 7 | "cmd": ["javac", "./${file_name}"], 8 | "selector": "source.java" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Default (Linux).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | { "keys": ["ctrl+alt+n"], "command": "new_snippet"}, 3 | { "keys": ["ctrl+alt+b"], "command": "cancel_build"} 4 | ] 5 | -------------------------------------------------------------------------------- /Default (Windows).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | { "keys": ["ctrl+alt+n"], "command": "new_snippet"}, 3 | { "keys": ["ctrl+alt+b"], "command": "cancel_build"} 4 | ] 5 | -------------------------------------------------------------------------------- /Java_completions.sublime-completions: -------------------------------------------------------------------------------- 1 | { 2 | "scope":"source.java", 3 | "completions": 4 | [ 5 | { "trigger": "Int", "contents": "Integer"}, 6 | { "trigger": "ri", "contents": "sc.nextInt()"}, 7 | { "trigger": "rl", "contents": "sc.nextLine()"}, 8 | { "trigger": "pr", "contents": "System.out.print($1);"}, 9 | { "trigger": "prl", "contents": "System.out.println($1);"}, 10 | { "trigger": "prf", "contents": "System.out.printf($1);"}, 11 | { "trigger": "fori", "contents": "for(Integer ${1:i} = ${2:0}; $1 < ${3:n}; ${4:++ $1}){\n\t$0\n}"}, 12 | { "trigger": "forqi", "contents": "for(Integer ${1:qi} = ${2:0}; $1 < ${3:qn}; ${4:++ $1}){\n\t$0\n}"}, 13 | { "trigger": "rofi", "contents": "for(Integer ${1:i} = ${2:n - 1}; $1 >= ${3:0}; ${4:-- $1}){\n\t$0\n}"}, 14 | { "trigger": "forgeneral", "contents": "for($1; $2; $3){\n\t$0\n}"}, 15 | { "trigger": "trav", "contents": "for(${1:Integer} $2: $3){\n\t$0\n}"}, 16 | { "trigger": "repeat", "contents": "for(Integer rep = ${1:n}; rep; -- rep){\n\t$0\n}"}, 17 | { "trigger": "while", "contents": "while($1){\n\t$0\n}"}, 18 | { "trigger": "dowhile", "contents": "do{\n\t$0\n}while($1);"}, 19 | { "trigger": "if", "contents": "if($1){\n\t$0\n}"}, 20 | { "trigger": "else if", "contents": "else if($1){\n\t$0\n}"}, 21 | { "trigger": "else", "contents": "else{\n\t$0\n}"}, 22 | { "trigger": "return", "contents": "return $1;"}, 23 | { "trigger": "exit", "contents": "System.exit(0);"}, 24 | ] 25 | } -------------------------------------------------------------------------------- /Kotlin.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | "extensions": 3 | [ 4 | "kt", 5 | "kts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /Library/Abstract_Algebra/Finite_Field/irreducibility_finite_field.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | bool irreducibility_finite_field(power_series p){ 6 | assert(p); 7 | p.reduce(); 8 | if((int)p.size() == 1) return true; 9 | int n = (int)p.size() - 1; 10 | auto gen = [&](int m){ 11 | power_series q{0, 1}; 12 | for(auto i = 0; i < m; ++ i) q.inplace_power_mod(FF::size, p); 13 | q += power_series{0, 1}; 14 | return q % p; 15 | }; 16 | for(auto pf = 2, x = n; pf <= x; ++ pf) if(x % pf == 0){ 17 | if((int)gcd(gen(n / pf), p).size() != 1) return false; 18 | while(x % pf == 0) x /= pf; 19 | } 20 | return !gen(n); 21 | } 22 | ]]> 23 | 24 | irreducibility_finite_field --> 25 | 26 | source.c++ --> 27 | 28 | -------------------------------------------------------------------------------- /Library/Abstract_Algebra/Lambda_Operations/lambda_arithmetic_monoid_action.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | ; 5 | auto TT = [&](const T &x, const T &y)->T{ 6 | return { 7 | x[0] + y[0] + y[1] * x[2], 8 | x[1] + y[1], 9 | x[2] + y[2], 10 | ~x[3] ? x[3] : y[3] 11 | }; 12 | }; 13 | T T_id{0, 0, 0, -1}; 14 | // a[i] += [0] + [1] * i 15 | using U = array; 16 | auto UU = [&](const U &f, const U &g)->U{ 17 | return { 18 | f[0] + g[0], 19 | f[1] + g[1] 20 | }; 21 | }; 22 | U U_id{}; 23 | auto UT = [&](const U &f, const T &x)->T{ 24 | return { 25 | x[0] + f[0] * x[2] * (x[2] - 1) / 2 + f[1] * ((x[3] + x[2] - 1) * (x[3] + x[2]) * (2 * x[3] + 2 * x[2] - 1) / 6 - (x[3] - 1) * x[3] * (2 * x[3] - 1) / 6 - x[3] * (2 * x[3] + x[2] - 1) * x[2] / 2), 26 | x[1] + f[0] * x[2] + f[1] * (2 * x[3] + x[2] - 1) * x[2] / 2, 27 | x[2], 28 | x[3] 29 | }; 30 | }; 31 | ]]> 32 | 33 | lambda_arithmetic_monoid_action --> 34 | 35 | source.c++ --> 36 | 37 | -------------------------------------------------------------------------------- /Library/Abstract_Algebra/cosets.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > cosets(int n, auto op, const vector &s){ 6 | vector> res{s}; 7 | vector in_res(n); 8 | for(auto x: s) in_res[x] = true; 9 | for(auto x = 0; x < n; ++ x) if(!in_res[x]){ 10 | res.emplace_back(); 11 | for(auto y: s){ 12 | int z = op(x, y); 13 | assert(!in_res[z]); 14 | res.back().push_back(z); 15 | in_res[z] = true; 16 | } 17 | } 18 | return res; 19 | } 20 | vector> cosets(const vector> &g, const vector &s){ 21 | return cosets((int)g.size(), [&](int x, int y){ return g[x][y]; }, s); 22 | } 23 | ]]> 24 | 25 | cosets --> 26 | 27 | source.c++ --> 28 | 29 | -------------------------------------------------------------------------------- /Library/Abstract_Algebra/group.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | struct group{ 6 | // Modify begin 7 | T data = 0; 8 | bool operator==(const group &x) const{ 9 | return data == x.data; 10 | } 11 | group &operator+=(const group &x){ 12 | data += x.data; 13 | return *this; 14 | } 15 | group &operator-=(const group &x){ 16 | data -= x.data; 17 | return *this; 18 | } 19 | template 20 | group &operator*=(U e){ 21 | if(e < 0){ 22 | *this = -*this; 23 | e = -e; 24 | } 25 | group res{}; 26 | for(; e; e >>= 1, *this = *this * *this) if(e & 1) res += *this; 27 | return *this = res; 28 | } 29 | friend ostream &operator<<(ostream &out, const group &x){ 30 | return out << x.data; 31 | } 32 | // Modify end 33 | bool operator!=(const group &x) const{ 34 | return !(*this == x); 35 | } 36 | group operator+(const group &x) const{ 37 | return group(*this) += x; 38 | } 39 | group operator+() const{ 40 | return *this; 41 | } 42 | group operator-(const group &x) const{ 43 | return group(*this) -= x; 44 | } 45 | group operator-() const{ 46 | return group() - *this; 47 | } 48 | template 49 | group operator*(U e) const{ 50 | return group(*this) *= e; 51 | } 52 | }; 53 | ]]> 54 | 55 | group --> 56 | 57 | source.c++ --> 58 | 59 | -------------------------------------------------------------------------------- /Library/Abstract_Algebra/monoid.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | struct monoid{ 6 | // Modify begin 7 | T data = 0; 8 | bool operator==(const monoid &x) const{ 9 | return data == x.data; 10 | } 11 | monoid &operator+=(const monoid &x){ 12 | data += x.data; 13 | return *this; 14 | } 15 | template 16 | monoid &operator*=(U e){ 17 | assert(e >= 0); 18 | monoid res{}; 19 | for(; e; e >>= 1, *this = *this * *this) if(e & 1) res += *this; 20 | return *this = res; 21 | } 22 | template 23 | friend ostream_t &operator<<(ostream_t &out, const monoid &x){ 24 | return out << x.data; 25 | } 26 | // Modify end 27 | bool operator!=(const monoid &x) const{ 28 | return !(*this == x); 29 | } 30 | monoid operator+(const monoid &x) const{ 31 | return monoid(*this) += x; 32 | } 33 | monoid operator+() const{ 34 | return *this; 35 | } 36 | template 37 | monoid operator*(U e) const{ 38 | return monoid(*this) *= e; 39 | } 40 | }; 41 | ]]> 42 | 43 | monoid --> 44 | 45 | source.c++ --> 46 | 47 | -------------------------------------------------------------------------------- /Library/Abstract_Algebra/nimber_product.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > i; ++ i) if(x >> i & 1) for(auto j = 0; j < 64 && y >> j; ++ j) if(y >> j & 1) res ^= bit_prod[i][j]; 18 | return res; 19 | } 20 | }; 21 | ]]> 22 | 23 | nimber_product --> 24 | 25 | source.c++ --> 26 | 27 | -------------------------------------------------------------------------------- /Library/Abstract_Algebra/quotient_group.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | >, 2> quotient_group(int n, auto op, const vector &s){ 6 | vector> cosets{s}; 7 | vector in_cosets(n), id(n, -1); 8 | for(auto x: s) in_cosets[x] = true, id[x] = 0; 9 | for(auto x = 0; x < n; ++ x) if(!in_cosets[x]){ 10 | cosets.emplace_back(); 11 | for(auto y: s){ 12 | int z = op(x, y); 13 | assert(!in_cosets[z]); 14 | cosets.back().push_back(z); 15 | in_cosets[z] = true; 16 | id[z] = (int)cosets.size() - 1; 17 | } 18 | } 19 | vector> qop((int)cosets.size(), vector((int)cosets.size())); 20 | for(auto i = 0; i < (int)cosets.size(); ++ i) for(auto j = 0; j < (int)cosets.size(); ++ j) qop[i][j] = id[op(cosets[i][0], cosets[j][0])]; 21 | return {qop, cosets}; 22 | } 23 | array>, 2> quotient_group(const vector> &g, const vector &s){ 24 | return quotient_group((int)g.size(), [&](int x, int y){ return g[x][y]; }, s); 25 | } 26 | ]]> 27 | 28 | quotient_group --> 29 | 30 | source.c++ --> 31 | 32 | -------------------------------------------------------------------------------- /Library/Abstract_Algebra/test_closedness.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | &s){ 6 | vector in_s(n); 7 | for(auto x: s){ 8 | assert(0 <= x && x < n); 9 | in_s[x] = true; 10 | } 11 | for(auto x: s) for(auto y: s) if(!in_s[op(x, y)]) return false; 12 | return true; 13 | } 14 | bool test_closedness(const vector> &g, const vector &s){ 15 | return test_closedness((int)g.size(), [&](int x, int y){ return g[x][y]; }, s); 16 | } 17 | ]]> 18 | 19 | test_closedness --> 20 | 21 | source.c++ --> 22 | 23 | -------------------------------------------------------------------------------- /Library/Abstract_Algebra/test_commutative_group_isomorphism.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | {0, ..., n-1} must define commutative groups. 5 | // Requires find_the_order_of_all_group_elements 6 | bool test_commutative_group_isomorphism(int n, auto op1, auto op2, const vector &order1, const vector &order2){ 7 | assert(1 <= n); 8 | vector cnt1(n), cnt2(n); 9 | for(auto x: order1) ++ cnt1[x - 1]; 10 | for(auto x: order2) ++ cnt2[x - 1]; 11 | return cnt1 == cnt2; 12 | } 13 | // Extra 2n op() calls to find the orders. 14 | bool test_commutative_group_isomorphism(int n, auto op1, auto op2){ 15 | return test_commutative_group_isomorphism(n, op1, op2, find_the_order_of_all_group_elements(n, op1), find_the_order_of_all_group_elements(n, op2)); 16 | } 17 | // Extra 2n op() calls to find the orders. 18 | bool test_commutative_group_isomorphism(const vector> &g, const vector> &h){ 19 | assert((int)g.size() == (int)h.size()); 20 | return test_commutative_group_isomorphism((int)g.size(), [&](int x, int y){ return g[x][y]; }, [&](int x, int y){ return h[x][y]; }, find_the_order_of_all_group_elements(g), find_the_order_of_all_group_elements(h)); 21 | } 22 | ]]> 23 | 24 | test_commutative_group_isomorphism --> 25 | 26 | source.c++ --> 27 | 28 | -------------------------------------------------------------------------------- /Library/Abstract_Algebra/test_commutative_group_nilpotency.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | {0, ..., n-1} must define a commutative group. 5 | // Requires find_the_order_of_all_group_elements 6 | bool test_commutative_group_nilpotency(int n, auto op, const vector &order){ 7 | assert(1 <= n); 8 | vector cnt(n); 9 | for(auto x: order) ++ cnt[x - 1]; 10 | for(auto p = 2, m = n; p <= m; ++ p){ 11 | if(m % p) continue; 12 | int power = 1, c = 1; 13 | for(; m % p == 0; m /= p, power *= p) c += cnt[power * p - 1]; 14 | if(c != power) return false; 15 | } 16 | return true; 17 | } 18 | // Extra 2n op() calls to find the orders. 19 | bool test_commutative_group_nilpotency(int n, auto op){ 20 | return test_commutative_group_nilpotency(n, op, find_the_order_of_all_group_elements(n, op)); 21 | } 22 | // Extra 2n op() calls to find the orders. 23 | bool test_commutative_group_nilpotency(const vector> &g){ 24 | return test_commutative_group_nilpotency((int)g.size(), [&](int x, int y){ return g[x][y]; }, find_the_order_of_all_group_elements(g)); 25 | } 26 | ]]> 27 | 28 | test_commutative_group_nilpotency --> 29 | 30 | source.c++ --> 31 | 32 | -------------------------------------------------------------------------------- /Library/Abstract_Algebra/test_direct_product.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > &f){ 5 | int size = 1; 6 | for(const auto &s: f){ 7 | if(__builtin_mul_overflow_p(size, (int)s.size(), 0)) return false; 8 | size *= (int)s.size(); 9 | } 10 | if(n != size) return false; 11 | if(n == 1) return true; 12 | for(const auto &s: f) if(!test_normal_subgroup(n, op, s)) return false; 13 | vector flag(n); 14 | for(auto x: f[0]){ 15 | auto recurse = [&](auto self, int i, int x)->void{ 16 | if(i == (int)f.size()){ 17 | flag[x] = true; 18 | return; 19 | } 20 | for(auto y: f[i]) self(self, i + 1, op(x, y)); 21 | }; 22 | recurse(recurse, 1, x); 23 | } 24 | return all_of(flag.begin(), flag.end(), [&](int x){ return x; }); 25 | } 26 | bool test_direct_product(const vector> &g, const vector> &f){ 27 | return test_direct_product((int)g.size(), [&](int x, int y){ return g[x][y]; }, f); 28 | } 29 | ]]> 30 | 31 | test_direct_product --> 32 | 33 | source.c++ --> 34 | 35 | -------------------------------------------------------------------------------- /Library/Abstract_Algebra/test_group_axioms.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > &g){ 4 | int n = (int)g.size(); 5 | assert(n >= 1); 6 | int id = -1; 7 | for(auto x = 0; x < n; ++ x) for(auto y = 0; y < n; ++ y){ 8 | assert(0 <= g[x][y] && g[x][y] < n); 9 | if(g[x][y] == y) id = x; 10 | } 11 | if(!~id) return false; 12 | vector inv(n, -1); 13 | for(auto x = 0; x < n; ++ x) for(auto y = 0; y < n; ++ y){ 14 | if(g[x][y] == id) inv[x] = y; 15 | for(auto z = 0; z < n; ++ z) if(g[x][g[y][z]] != g[g[x][y]][z]) return false; 16 | } 17 | if(!~*min_element(inv.begin(), inv.end())) return false; 18 | return true; 19 | } 20 | ]]> 21 | 22 | test_group_axioms --> 23 | 24 | source.c++ --> 25 | 26 | -------------------------------------------------------------------------------- /Library/Abstract_Algebra/test_group_commutativity.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | {0, ..., n-1} must define a group. 5 | // Less than 3n + log(n)^2 op() calls. 6 | bool test_group_commutativity(int n, auto op){ 7 | assert(1 <= n); 8 | vector square(n), g, in_s(n), s; 9 | for(auto x = 0; x < n; ++ x) if(x == (square[x] = op(x, x))) s.push_back(x), in_s[x] = true; 10 | for(auto x = 0; x < n; ++ x){ 11 | if(in_s[x]) continue; 12 | for(auto y: g) if(op(x, y) != op(y, x)) return false; 13 | g.push_back(x); 14 | int size = (int)s.size(); 15 | for(auto y = x, z = square[x]; ; y = z, z = op(y, x)){ 16 | for(auto i = 0; i < size; ++ i) s.push_back(op(y, s[i])), in_s[s.back()] = true; 17 | if(in_s[z]) break; 18 | } 19 | } 20 | return true; 21 | } 22 | bool test_group_commutativity(const vector> &g){ 23 | return test_group_commutativity((int)g.size(), [&](int x, int y){ return g[x][y]; }); 24 | } 25 | ]]> 26 | 27 | test_group_commutativity --> 28 | 29 | source.c++ --> 30 | 31 | -------------------------------------------------------------------------------- /Library/Abstract_Algebra/test_normal_subgroup.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | &s){ 5 | if(s.empty() || !test_closedness(n, op, s)) return false; 6 | vector in_s(n), inv(n, -1); 7 | int id = -1; 8 | for(auto x: s){ 9 | assert(0 <= x && x < n); 10 | in_s[x] = true; 11 | if(op(x, x) == x) id = x; 12 | } 13 | assert(~id); 14 | for(auto x = 0; x < n; ++ x) if(!~inv[x]) for(auto y = x; y < n; ++ y) if(op(x, y) == id) inv[x] = y, inv[y] = x; 15 | for(auto x = 0; x < n; ++ x) if(!in_s[x]) for(auto y: s) if(!in_s[op(op(x, y), inv[x])]) return false; 16 | return true; 17 | } 18 | bool test_normal_subgroup(const vector> &g, const vector &s){ 19 | return test_normal_subgroup((int)g.size(), [&](int x, int y){ return g[x][y]; }, s); 20 | } 21 | ]]> 22 | 23 | test_normal_subgroup --> 24 | 25 | source.c++ --> 26 | 27 | -------------------------------------------------------------------------------- /Library/Combinatorial/Block_Minmax_Processor/block_minmax_processor.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > 7 | vector block_minmax_processor(const vector &a, int block, Compare cmp = less<>()){ 8 | int n = (int)a.size(); 9 | assert(1 <= block && block <= n); 10 | vector res(n - block + 1); 11 | deque dq; 12 | for(auto i = 0; i < block - 1; ++ i){ 13 | while(!dq.empty() && !cmp(a[dq.back()], a[i])) dq.pop_back(); 14 | dq.push_back(i); 15 | } 16 | for(auto i = block - 1; i < n; ++ i){ 17 | while(!dq.empty() && !cmp(a[dq.back()], a[i])) dq.pop_back(); 18 | dq.push_back(i); 19 | res[i - block + 1] = dq.front(); 20 | if(dq.front() == i - block + 1) dq.pop_front(); 21 | } 22 | return res; 23 | } 24 | ]]> 25 | 26 | block_minmax_processor --> 27 | 28 | source.c++ --> 29 | 30 | -------------------------------------------------------------------------------- /Library/Combinatorial/Flow_Matching_And_Cut/global_min_cut.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | pair> global_min_cut(vector> adjm){ 6 | int n = (int)adjm.size(); 7 | vector used(n); 8 | vector cut, best_cut; 9 | T best_weight = -1; 10 | for(auto phase = n - 1; phase >= 0; -- phase){ 11 | vector w = adjm[0]; 12 | vector added = used; 13 | int prev, k = 0; 14 | for(auto i = 0; i < phase; ++ i){ 15 | prev = k, k = -1; 16 | for(auto j = 1; j < n; ++ j) if(!added[j] && (k == -1 || w[j] > w[k])) k = j; 17 | if(i == phase - 1){ 18 | for(auto j = 0; j < n; ++ j) adjm[prev][j] += adjm[k][j]; 19 | for(auto j = 0; j < n; ++ j) adjm[j][prev] = adjm[prev][j]; 20 | used[k] = true, cut.push_back(k); 21 | if(best_weight == -1 || w[k] < best_weight) best_cut = cut, best_weight = w[k]; 22 | } 23 | else{ 24 | for(auto j = 0; j < n; ++ j) w[j] += adjm[k][j]; 25 | added[k] = true; 26 | } 27 | } 28 | } 29 | return {best_weight, best_cut}; 30 | } 31 | ]]> 32 | 33 | global_min_cut --> 34 | 35 | source.c++ --> 36 | 37 | -------------------------------------------------------------------------------- /Library/Combinatorial/Flow_Matching_And_Cut/gomory_hu.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | vector> gomory_hu_tree(int n, const vector> &edge){ 8 | flow_network F(n); 9 | for(auto &[u, v, w]: edge) F.link(u, v, w); 10 | vector> res(max(n - 1, 0)); 11 | vector pv(n), cut(n); 12 | for(auto i = 1; i < n; ++ i){ 13 | F.clear_flow(); 14 | auto [flow, left, right] = dinic_maximum_flow(F).minimum_cut(pv[i], i); 15 | fill(cut.begin(), cut.end(), 0); 16 | for(auto u: right) cut[u] = 1; 17 | for(auto j = i + 1; j < n; ++ j) if(cut[j] == cut[i] && pv[j] == pv[i]) pv[j] = i; 18 | res[i - 1] = {pv[i], i, flow}; 19 | } 20 | return res; 21 | } 22 | ]]> 23 | 24 | gomory_hu --> 25 | 26 | source.c++ --> 27 | 28 | -------------------------------------------------------------------------------- /Library/Combinatorial/Flow_Matching_And_Cut/hopcroft_karp_algorithm.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | n = n; 7 | this->m = m; 8 | adj.assign(n, {}); 9 | pu.assign(n, -1); 10 | pv.assign(m, -1); 11 | } 12 | int insert(int from, int to){ 13 | adj[from].push_back(to); 14 | return (int)adj[from].size() - 1; 15 | } 16 | void clear(){ 17 | adj.assign(n, {}); 18 | pu.assign(n, -1); 19 | pv.assign(m, -1); 20 | } 21 | vector a, p, q; 22 | int maximum_matching(){ 23 | int matching = 0; 24 | while(true){ 25 | fill(a.begin(), a.end(), -1); 26 | fill(p.begin(), p.end(), -1); 27 | int delta = 0, qend = 0; 28 | for(auto u = 0; u < n; ++ u) if(!~pu[u]) q[qend ++] = a[u] = p[u] = u; 29 | for(auto qbeg = 0; qbeg < qend; ++ qbeg){ 30 | int u = q[qbeg]; 31 | if(~pu[a[u]]) continue; 32 | for(auto v: adj[u]){ 33 | if(!~pv[v]){ 34 | while(~v) pv[v] = u, swap(pu[u], v), u = p[u]; 35 | ++ delta; 36 | break; 37 | } 38 | if(!~p[pv[v]]) q[qend ++] = v = pv[v], p[v] = u, a[v] = a[u]; 39 | } 40 | } 41 | if(!delta) break; 42 | matching += delta; 43 | } 44 | return matching; 45 | } 46 | }; 47 | ]]> 48 | 49 | hopcroft_karp_algorithm --> 50 | 51 | source.c++ --> 52 | 53 | -------------------------------------------------------------------------------- /Library/Combinatorial/Flow_Matching_And_Cut/kuhn_algorithm.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | n = n; 6 | this->m = m; 7 | adj.assign(n, {}); 8 | pu.assign(n, -1); 9 | pv.assign(m, -1); 10 | } 11 | int insert(int from, int to){ 12 | adj[from].push_back(to); 13 | return (int)adj[from].size() - 1; 14 | } 15 | void clear(){ 16 | adj.assign(n, {}); 17 | pu.assign(n, -1); 18 | pv.assign(m, -1); 19 | } 20 | int it = 0; 21 | vector was; 22 | bool dfs(int u){ 23 | was[u] = it; 24 | for(auto v: adj[u]) if(!~pv[v]){ 25 | pu[u] = v, pv[v] = u; 26 | return true; 27 | } 28 | for(auto v: adj[u]) if(was[pv[v]] != it && dfs(pv[v])){ 29 | pu[u] = v, pv[v] = u; 30 | return true; 31 | } 32 | return false; 33 | } 34 | // O((n + m) * (# of edges)) 35 | int maximum_matching(){ 36 | mt19937 rng(1564); 37 | for(auto u = 0; u < n; ++ u) shuffle(adj[u].begin(), adj[u].end(), rng); 38 | int matching = 0; 39 | while(true){ 40 | ++ it; 41 | int augment = 0; 42 | for(auto u = 0; u < n; ++ u) if(!~pu[u] && dfs(u)) ++ augment; 43 | if(!augment) break; 44 | matching += augment; 45 | } 46 | return matching; 47 | } 48 | int run_once(int u){ 49 | if(~pu[u]) return 0; 50 | ++ it; 51 | return dfs(u); 52 | } 53 | }; 54 | ]]> 55 | 56 | kuhn_algorithm --> 57 | 58 | source.c++ --> 59 | 60 | -------------------------------------------------------------------------------- /Library/Combinatorial/Flow_Matching_And_Cut/minimum_path_cover.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | vector> minimum_path_cover(const graph &g){ 8 | int n = g.n; 9 | hopcroft_karp_algorithm hk(n, n); 10 | for(auto id = 0; id < (int)g.edge.size(); ++ id){ 11 | if(g.ignore && g.ignore(id)) continue; 12 | auto &e = g.edge[id]; 13 | hk.insert(e.from, e.to); 14 | } 15 | int size_matching = hk.maximum_matching(); 16 | vector> path_cover; 17 | for(auto s = 0; s < n; ++ s){ 18 | if(~hk.pv[s]) continue; 19 | vector path{s}; 20 | for(auto u = s; ~hk.pu[u]; u = hk.pu[u]) for(auto id: g.adj[u]) if(g.edge[id].to == hk.pu[u]) path.push_back(id); 21 | path_cover.push_back(path); 22 | } 23 | assert(size_matching + (int)path_cover.size() == n); 24 | return path_cover; 25 | } 26 | ]]> 27 | 28 | minimum_path_cover --> 29 | 30 | source.c++ --> 31 | 32 | -------------------------------------------------------------------------------- /Library/Combinatorial/Longest_Monotone_Subsequence/longest_increasing_bisubsequence.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | , class CompareU = less<>> 6 | vector longest_increasing_bisubsequence(const vector &a, const vector &b, CompareT cmpT = less<>(), CompareU cmpU = less<>()){ 7 | int n = (int)a.size(); 8 | assert((int)b.size() == n); 9 | auto cmp = [&](int i, int j)->bool{ 10 | return cmpT(a[i], a[j]) ? true : cmpT(a[j], a[i]) ? false : cmpU(b[i], b[j]); 11 | }; 12 | vector> active; 13 | vector prev(n, -1); 14 | for(auto i = 0; i < n; ++ i){ 15 | auto it = partition_point(active.begin(), active.end(), [&](const auto &s){ 16 | auto it = s.lower_bound(i); 17 | return it != s.begin() && cmpU(b[*std::prev(it)], b[i]); 18 | }); 19 | if(it != active.begin()) prev[i] = *std::prev(std::prev(it)->lower_bound(i)); 20 | if(it == active.end()) active.push_back(set(cmp)), it = std::prev(active.end()); 21 | auto &s = *it; 22 | for(auto it2 = next(s.insert(i).first); it2 != s.end() && cmpU(b[i], b[*it2]); it2 = s.erase(it2)); 23 | } 24 | int len = (int)active.size(), cur = *active.back().begin(); 25 | vector res(len); 26 | while(len --) res[len] = cur, cur = prev[cur]; 27 | return res; 28 | } 29 | ]]> 30 | 31 | longest_increasing_bisubsequence --> 32 | 33 | source.c++ --> 34 | 35 | -------------------------------------------------------------------------------- /Library/Combinatorial/Longest_Monotone_Subsequence/longest_monotone_subsequence.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > 6 | vector longest_monotone_subsequence(const vector &a, Compare cmp = less<>()){ 7 | // less: longest increasing subsequence 8 | // less_equal: longest non-decreasing subsequence 9 | // greater: longest decreasing subsequence 10 | // greater_equal: longest non-increasing subsequence 11 | if(a.empty()) return {}; 12 | int n = (int)a.size(); 13 | vector prev(n), active; 14 | for(auto i = 0; i < n; ++ i){ 15 | auto it = partition_point(active.begin(), active.end(), [&](int j){ return cmp(a[j], a[i]); }); 16 | if(it == active.end()) active.emplace_back(), it = std::prev(active.end()); 17 | *it = i; 18 | prev[i] = it == active.begin() ? -1 : *std::prev(it); 19 | } 20 | int len = (int)active.size(), cur = active.back(); 21 | vector res(len); 22 | while(len --) res[len] = cur, cur = prev[cur]; 23 | return res; 24 | } 25 | ]]> 26 | 27 | longest_monotone_subsequence --> 28 | 29 | source.c++ --> 30 | 31 | -------------------------------------------------------------------------------- /Library/Combinatorial/Permutation/count_inversions.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > 5 | long long count_inversions(const vector &a, bool count_equal = false, Compare cmp = less<>()){ 6 | int n = (int)a.size(); 7 | vector cmpr = a; 8 | sort(cmpr.begin(), cmpr.end(), cmp); 9 | vector sum(n); 10 | long long res = 0; 11 | for(auto i = 0; i < n; ++ i){ 12 | int p = lower_bound(cmpr.begin(), cmpr.end(), a[i], cmp) - cmpr.begin(); 13 | res += i; 14 | for(auto r = p + !count_equal; r > 0; r -= r & -r) res -= sum[r - 1]; 15 | for(++ p; p <= n; p += p & -p) ++ sum[p - 1]; 16 | } 17 | return res; 18 | } 19 | ]]> 20 | 21 | count_inversions --> 22 | 23 | source.c++ --> 24 | 25 | -------------------------------------------------------------------------------- /Library/Combinatorial/Submodularity/check_antisubmodularity.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | optional> check_antisubmodularity(const vector &a){ 7 | int n = (int)a.size(); 8 | assert(n >= 1 && __builtin_popcount(n) == 1); 9 | int w = __lg(n); 10 | for(auto x = 0; x < n; ++ x) for(auto i = 0; i < w; ++ i) if(~x >> i & 1) for(auto j = i + 1; j < w; ++ j) if(~x >> j & 1) if(a[x | 1 << i] + a[x | 1 << j] < a[x] + a[x | 1 << i | 1 << j]) return array{x | 1 << i, x | 1 << j}; 11 | return {}; 12 | } 13 | ]]> 14 | 15 | check_antisubmodularity --> 16 | 17 | source.c++ --> 18 | 19 | -------------------------------------------------------------------------------- /Library/Combinatorial/Young_Tableau/RSK_inverse_mapping.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | RSK_inverse_mapping(vector> s, vector> t){ 7 | assert((int)s.size() == (int)t.size()); 8 | int n = 0; 9 | for(auto i = 0; i < (int)s.size(); ++ i){ 10 | assert((int)s[i].size() == (int)t[i].size()); 11 | n += (int)s[i].size(); 12 | } 13 | vector p(n); 14 | for(auto ind = n - 1; ind >= 0; -- ind){ 15 | int i = 0, j = 0; 16 | for(; i < (int)t.size(); ++ i){ 17 | for(j = 0; j < (int)t[i].size() && t[i][j] != ind; ++ j){} 18 | if(j < (int)t[i].size()) break; 19 | } 20 | int x = s[i][j]; 21 | s[i].pop_back(), t[i].pop_back(); 22 | for(-- i; i >= 0; -- i){ 23 | j = upper_bound(s[i].begin(), s[i].end(), x) - s[i].begin(); 24 | swap(s[i][j - 1], x); 25 | } 26 | p[ind] = x; 27 | } 28 | return p; 29 | } 30 | ]]> 31 | 32 | RSK_inverse_mapping --> 33 | 34 | source.c++ --> 35 | 36 | -------------------------------------------------------------------------------- /Library/Combinatorial/Young_Tableau/RSK_mapping.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | >, 2> RSK_mapping(const vector &p){ 8 | int n = (int)p.size(); 9 | { // Check if p is a permutation 10 | vector flag(n); 11 | for(auto x: p){ 12 | assert(0 <= x && x < n && !flag[x]); 13 | flag[x] = true; 14 | } 15 | } 16 | vector> s, t; 17 | for(auto ind = 0; ind < n; ++ ind){ 18 | int x = p[ind]; 19 | bool found = false; 20 | for(auto i = 0; i < (int)s.size(); ++ i){ 21 | int j = upper_bound(s[i].begin(), s[i].end(), x) - s[i].begin(); 22 | if(j == (int)s[i].size()){ 23 | s[i].push_back(x), t[i].push_back(ind); 24 | found = true; 25 | break; 26 | } 27 | swap(s[i][j], x); 28 | } 29 | if(!found) s.emplace_back(vector{x}), t.emplace_back(vector{ind}); 30 | } 31 | return {s, t}; 32 | } 33 | ]]> 34 | 35 | RSK_mapping --> 36 | 37 | source.c++ --> 38 | 39 | -------------------------------------------------------------------------------- /Library/Combinatorial/Young_Tableau/count_young_tableaux.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | T count_young_tableaux(const vector &lambda){ 7 | for(auto i = 0; i < (int)lambda.size() - 1; ++ i){ 8 | assert(lambda[i] >= lambda[i + 1]); 9 | assert(lambda[i + 1] >= 0); 10 | } 11 | T res = 1; 12 | for(auto h = (int)lambda.size(), y = 0; y < lambda[0]; ++ y){ 13 | while(h && lambda[h - 1] <= y) -- h; 14 | for(auto i = 0; i < h; ++ i) res *= lambda[i] - y + h - i - 1; 15 | } 16 | res = 1 / res; 17 | for(auto x = accumulate(lambda.begin(), lambda.end(), 0); x >= 1; -- x) res *= x; 18 | return res; 19 | } 20 | ]]> 21 | 22 | count_young_tableaux --> 23 | 24 | source.c++ --> 25 | 26 | -------------------------------------------------------------------------------- /Library/Combinatorial/compute_sum_of_non_intersecting_tuples_of_paths.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | to, P is vertex-non-intersecting}sign(P)*\prod_{e: edge in P} w(e). 5 | // G must be a DAG with a valid topological order order. 6 | // Requires graph 7 | template, class F2 = multiplies<>> 8 | T compute_sum_of_non_intersecting_tuples_of_paths(const graph &g, const vector &order, const vector &from, const vector &to, auto determinant, T _type_deducer, F1 add = plus<>(), F2 multiply = multiplies<>()){ 9 | assert((int)from.size() == (int)to.size()); 10 | assert(g.n == (int)order.size()); 11 | int n = (int)from.size(); 12 | vector> M(n, vector(n)); 13 | vector dp(g.n); 14 | for(auto i = 0; i < n; ++ i){ 15 | fill(dp.begin(), dp.end(), 0); 16 | dp[from[i]] = 1; 17 | for(auto u: order) for(auto id: g.adj[u]){ 18 | if(g.ignore && g.ignore(id)) continue; 19 | dp[g(u, id)] += dp[u] * g.edge[id].cost; 20 | } 21 | for(auto j = 0; j < n; ++ j) M[i][j] = dp[to[j]]; 22 | } 23 | return determinant(M); 24 | } 25 | ]]> 26 | 27 | hello --> 28 | 29 | source.c++ --> 30 | 31 | -------------------------------------------------------------------------------- /Library/Data_Structure/Data_Structure_Enhancer/data_structure_insertion_enabler_online.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | struct data_structure_insertion_enabler_online{ 6 | int n; // Elements should lie in range [0, n). 7 | vector element; 8 | B build; // build(id, a): build the DS with updates in a and assign it to bucket id. 9 | C clear; // clear(id): assign empty DS to bucket id. 10 | data_structure_insertion_enabler_online(int n, B build, C clear): n(n), build(build), clear(clear){ 11 | assert(n >= 0); 12 | } 13 | // Insert update i. 14 | // Amortized O(clear() + build(n) / n) 15 | void insert(int i){ 16 | assert(0 <= i && i < n); 17 | element.push_back(i); 18 | int id = __builtin_ctz((int)element.size()); 19 | build(id, {(int)element.size() - (1 << id), (int)element.size()}); 20 | for(auto idprev = 0; idprev < id; ++ idprev) clear(idprev); 21 | } 22 | }; 23 | ]]> 24 | 25 | data_structure_insertion_enabler_online --> 26 | 27 | source.c++ --> 28 | 29 | -------------------------------------------------------------------------------- /Library/Data_Structure/Disjoint_Set/persistent_disjoint_set.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | par): p{move(par)}{ } 7 | persistent_disjoint_set(): p{}{ } 8 | persistent_disjoint_set(const persistent_disjoint_set &) = default; 9 | persistent_disjoint_set(persistent_disjoint_set &&) = default; 10 | persistent_disjoint_set &operator=(const persistent_disjoint_set &) = default; 11 | persistent_disjoint_set &operator=(persistent_disjoint_set &&) = default; 12 | persistent_disjoint_set merge(int x, int y) const{ 13 | x = root(x), y = root(y); 14 | if(x == y) return *this; 15 | // Ensure x is bigger than y. 16 | int x_size = -p[x].value_or(-1), y_size = -p[y].value_or(-1); 17 | if(x_size < y_size) swap(x, y), swap(x_size, y_size); 18 | return persistent_disjoint_set(p.set(x, -(x_size + y_size)).set(y, x)); 19 | } 20 | int root(int x) const{ 21 | const optional &par = p[x]; 22 | return !par || *par < 0 ? x : root(*par); 23 | } 24 | bool share(int x, int y) const{ 25 | return root(x) == root(y); 26 | } 27 | int size(int x) const{ 28 | return -(p[root(x)].value_or(-1)); 29 | } 30 | private: 31 | persistent_array p; 32 | }; 33 | ]]> 34 | 35 | persistent_disjoint_set --> 36 | 37 | source.c++ --> 38 | 39 | -------------------------------------------------------------------------------- /Library/Data_Structure/Range_Inversion_Query_Solver/range_inversion_query_solver_offline.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | struct range_inversion_query_solver_offline{ 6 | int n; 7 | vector data; 8 | mo_sweepline_base, minus<>> mo; 9 | template> 10 | range_inversion_query_solver_offline(const vector &a, Compare cmp = less<>()): n((int)a.size()), data((int)a.size()), mo(n, plus<>(), 0LL, minus<>()){ 11 | vector temp = a; 12 | sort(temp.begin(), temp.end(), cmp); 13 | for(auto i = 0; i < n; ++ i) data[i] = lower_bound(temp.begin(), temp.end(), a[i]) - temp.begin(); 14 | } 15 | void query(int qi, int ql, int qr){ 16 | mo.query(qi, ql, qr); 17 | } 18 | // O(n*BX + qn*BX + n^2/BX) 19 | vector solve() const{ 20 | sqrt_decomposition_heavy_point_update_light_range_query_commutative_group, minus<>> sqrtdecomp(n, plus<>(), 0, minus<>()); 21 | auto insert = [&](int i)->void{ 22 | sqrtdecomp.update(data[i], 1); 23 | }; 24 | auto query_left = [&](int i)->int{ 25 | return sqrtdecomp.query(0, data[i]); 26 | }; 27 | auto query_right = [&](int i)->int{ 28 | return sqrtdecomp.query(data[i] + 1, n); 29 | }; 30 | return mo.solve(insert, query_left, query_right); 31 | } 32 | }; 33 | ]]> 34 | 35 | range_inversion_query_solver_offline --> 36 | 37 | source.c++ --> 38 | 39 | -------------------------------------------------------------------------------- /Library/Data_Structure/Sqrt_Decomposition/mo_2d_hilbert_curve_ordering.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | curve; 11 | vector> points; 12 | mo_2d_hilbert_curve_ordering(int level): curve(level){ } 13 | void query(int qi, int x, int y){ 14 | points.push_back({curve.order(x, y), x, y, qi}); 15 | } 16 | // starting from (0, 0), access each points and execute queries 17 | void solve(auto inc_x, auto dec_x, auto inc_y, auto dec_y, auto process){ 18 | sort(points.begin(), points.end()); 19 | int x = 0, y = 0; 20 | for(auto &[ignore, qx, qy, qi]: points){ 21 | while(qx < x) dec_x(), -- x; 22 | while(y < qy) inc_y(), ++ y; 23 | while(x < qx) inc_x(), ++ x; 24 | while(qy < y) dec_y(), -- y; 25 | process(qi); 26 | } 27 | } 28 | }; 29 | ]]> 30 | 31 | mo_2d_hilbert_curve_ordering --> 32 | 33 | source.c++ --> 34 | 35 | -------------------------------------------------------------------------------- /Library/Data_Structure/Sqrt_Decomposition/mo_2d_rollback.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | struct mo_2d_rollback{ 5 | vector> query; 6 | void insert(int qi, int l, int r){ 7 | query.push_back({l, r, qi}); 8 | } 9 | void solve(auto insert_left, auto insert_right, auto time, auto reverse_to, auto answer){ 10 | auto cmp = [&](const auto &p, const auto &q)->bool{ 11 | return p[0] / BX != q[0] / BX ? p < q : p[1] < q[1]; 12 | }; 13 | sort(query.begin(), query.end(), cmp); 14 | int init = time(); 15 | for(auto [ql, qr, qi]: query){ 16 | if(qr - ql <= BX){ 17 | for(auto i = ql; i < qr; ++ i) insert_right(i); 18 | answer(qi); 19 | reverse_to(init); 20 | } 21 | } 22 | int last_block = -1, l, r; 23 | for(auto [ql, qr, qi]: query){ 24 | if(qr - ql <= BX) continue; 25 | int block = ql / BX; 26 | if(block != last_block){ 27 | reverse_to(init); 28 | l = (block + 1) * BX, r = qr; 29 | for(auto i = l; i < r; ++ i) insert_right(i); 30 | last_block = block; 31 | } 32 | while(r < qr) insert_right(r ++); 33 | int t = time(); 34 | for(auto i = l - 1; i >= ql; -- i) insert_left(i); 35 | answer(qi); 36 | reverse_to(t); 37 | } 38 | } 39 | }; 40 | ]]> 41 | 42 | mo_2d_rollback --> 43 | 44 | source.c++ --> 45 | 46 | -------------------------------------------------------------------------------- /Library/Dynamic_Programming/monotone_queue_optimization.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | pair, vector> monotone_queue_optimization(const vector &init, auto cost){ 5 | assert(!init.empty()); 6 | int n = (int)init.size(); 7 | vector dp = init; 8 | vector prev(n, -1); 9 | auto cross = [&](int i, int j){ 10 | int l = j, r = n; 11 | while(r - l > 1){ 12 | int mid = l + r >> 1; 13 | if constexpr(GET_MAX) dp[i] + cost(i, mid) >= dp[j] + cost(j, mid) ? l = mid : r = mid; 14 | else dp[i] + cost(i, mid) <= dp[j] + cost(j, mid) ? l = mid : r = mid; 15 | } 16 | return l; 17 | }; 18 | deque q{0}; 19 | for(auto i = 1; i < n; ++ i){ 20 | auto x = cost(q.front(), i); 21 | if constexpr(GET_MAX){ 22 | while(q.size() > 1 && dp[q[0]] + cost(q[0], i) < dp[q[1]] + cost(q[1], i)) q.pop_front(); 23 | if(dp[i] < dp[q.front()] + x){ 24 | dp[i] = dp[q.front()] + x; 25 | prev[i] = q.front(); 26 | } 27 | } 28 | else{ 29 | while((int)q.size() > 1 && dp[q[0]] + cost(q[0], i) > dp[q[1]] + cost(q[1], i)) q.pop_front(); 30 | if(dp[i] > dp[q.front()] + x){ 31 | dp[i] = dp[q.front()] + x; 32 | prev[i] = q.front(); 33 | } 34 | } 35 | while((int)q.size() > 1 && cross(*next(q.rbegin()), *q.rbegin()) >= cross(*q.rbegin(), i)) q.pop_back(); 36 | q.push_back(i); 37 | } 38 | return {dp, prev}; 39 | } 40 | ]]> 41 | 42 | monotone_queue_optimization --> 43 | 44 | source.c++ --> 45 | 46 | -------------------------------------------------------------------------------- /Library/Geometry/Circle/circle_polygon_intersection.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | double circle_polygon_intersection(const point &c, T r, const vector> &a){ 8 | auto arg = [&](const point &p, const point &q)->double{ 9 | return atan2(p ^ q, p * q); 10 | }; 11 | auto f = [&](const point &p, const point &q)->double{ 12 | double r2 = r * r / 2.0; 13 | auto d = q - p, b = d * p * 1.0 / (d * d), c = (p * p - r * r) * 1.0 / (d * d), det = b * b - c; 14 | if(det <= 0) return arg(p, q) * r2; 15 | auto s = max(0.0, -b - sqrt(det)), t = min(1.0, -b + sqrt(det)); 16 | if(t < 0 || 1 <= s) return arg(p, q) * r2; 17 | auto u = p + d * s, v = p + d * t; 18 | return arg(p, u) * r2 + (u ^ v) / 2.0 + arg(v, q) * r2; 19 | }; 20 | T res = 0; 21 | for(auto i = 0; i < (int)a.size(); ++ i) res += f(point(a[i] - c), point(a[(i + 1) % (int)a.size()] - c)); 22 | return res; 23 | } 24 | ]]> 25 | 26 | circle_polygon_intersection --> 27 | 28 | source.c++ --> 29 | 30 | -------------------------------------------------------------------------------- /Library/Geometry/Circle/minimum_enclosing_circle.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | pair, double> minimum_enclosing_circle(vector> a){ 7 | int n = (int)a.size(); 8 | shuffle(a.begin(), a.end(), mt19937(1564)); 9 | point o = a[0]; 10 | double r = 0, EPS = 1 + 1e-8; 11 | for(auto i = 0; i < n; ++ i) if((o - a[i]).norm() > r * EPS){ 12 | o = a[i], r = 0; 13 | for(auto j = 0; j < i; ++ j) if((o - a[j]).norm() > r * EPS){ 14 | o = (a[i] + a[j]) / 2, r = (o - a[i]).norm(); 15 | for(auto k = 0; k < j; ++ k) if((o - a[k]).norm() > r * EPS){ 16 | o = circumcenter(a[i], a[j], a[k]), r = (o - a[i]).norm(); 17 | } 18 | } 19 | } 20 | return {o, r}; 21 | } 22 | ]]> 23 | 24 | minimum_enclosing_circle --> 25 | 26 | source.c++ --> 27 | 28 | -------------------------------------------------------------------------------- /Library/Geometry/Circle/radical_axis.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | optional> radical_axis(const point &c1, T r1, const point &c2, T r2){ 8 | if(c1 == c2) return {}; 9 | auto d = c2 - c1; 10 | return {{(c1 * (d * d - r1 * r1 + r2 * r2) + c2 * (d * d + r1 * r1 - r2 * r2)) / (2 * d * d), {-d.y, d.x}, false}}; 11 | } 12 | ]]> 13 | 14 | radical_axis --> 15 | 16 | source.c++ --> 17 | 18 | -------------------------------------------------------------------------------- /Library/Geometry/Convex_Polygon/convex_polygon_diameter.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | array convex_polygon_diameter(const convex_polygon &c){ 8 | assert(!c.empty()); 9 | #define NEXT(i) i < (int)c.size() - 1 ? i + 1 : 0 10 | if((int)c.size() == 1) return {0, 0}; 11 | pair> res{0, {0, 0}}; 12 | for(auto i = 0, j = 1; i < (int)c.size(); ++ i){ 13 | while(true){ 14 | res = max(res, decltype(res){squared_distance(c[i], c[j]), {i, j}}); 15 | if((c[NEXT(i)] - c[i] ^ c[NEXT(j)] - c[j]) <= 0) break; 16 | j = NEXT(j); 17 | } 18 | } 19 | #undef NEXT 20 | return res.second; 21 | } 22 | ]]> 23 | 24 | convex_polygon_diameter --> 25 | 26 | source.c++ --> 27 | 28 | -------------------------------------------------------------------------------- /Library/Geometry/Convex_Polygon/convex_polygon_extreme_point.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 8 | int convex_polygon_extreme_point(const convex_polygon &c, const point &p){ 9 | assert(!c.empty()); 10 | auto q = p.perp(); 11 | if((int)c.size() == 1 || (c[0] - c.back() ^ q) >= 0 && (q ^ c[1] - c[0]) >= 0) return 0; 12 | int low = 0, high = (int)c.size() - 1; 13 | while(high - low >= 2){ 14 | int mid = low + (high - low >> 1); 15 | (is_sorted_by_angle(point(), c[low + 1] - c[low], c[mid + 1] - c[mid], q) ? low : high) = mid; 16 | } 17 | return high; 18 | } 19 | ]]> 20 | 21 | convex_polygon_extreme_point --> 22 | 23 | source.c++ --> 24 | 25 | -------------------------------------------------------------------------------- /Library/Geometry/Line/line_to_line_distance.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | double distance_between_rays(const line &L, const line &M){ 6 | if(L.parallel_to(M)){ 7 | if(L.d * M.d >= 0 || (M.p - L.p) * M.d <= 0) return distance_to_line(L.p, M); 8 | else return distance(L.p, M.p); 9 | } 10 | else{ 11 | if(intersect_no_parallel_overlap<1, 0, 1, 0, T>(L, M).first) return 0; 12 | else return min(distance_to_ray(L.p, M), distance_to_ray(M.p, L)); 13 | } 14 | } 15 | template 16 | double distance_between_segments(const line &L, const line &M){ 17 | if(intersect_closed_segments(L, M).first) return 0; 18 | return min({distance_to_segment(L.p, M), distance_to_segment(L.q(), M), distance_to_segment(M.p, L), distance_to_segment(M.q(), L)}); 19 | } 20 | ]]> 21 | 22 | line_to_line_distance --> 23 | 24 | source.c++ --> 25 | 26 | -------------------------------------------------------------------------------- /Library/Geometry/Norm/find_a_closest_pair.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | ), class F2 = decltype(::sqrt)> 8 | pair> find_a_closest_pair(const vector> &a, F1 distance_powered = squared_distance, F2 get_distance = sqrt){ 9 | int n = (int)a.size(); 10 | assert(n >= 2); 11 | vector order(n); 12 | iota(order.begin(), order.end(), 0); 13 | sort(order.begin(), order.end(), [&](int i, int j){ return a[i].y < a[j].y; }); 14 | for(auto t = 1; t < n; ++ t) if(a[order[t - 1]] == a[order[t]]) return {0, {order[t - 1], order[t]}}; 15 | pair> res{numeric_limits::max() / 2, {}}; 16 | map, int> s; 17 | int t = 0; 18 | for(auto i: order){ 19 | T d = 1 + get_distance(res.first); 20 | while(a[order[t]].y <= a[i].y - d) s.erase(a[order[t]]), ++ t; 21 | auto low = s.lower_bound({a[i].x - d, a[i].y}); 22 | auto high = s.upper_bound({a[i].x + d, a[i].y}); 23 | for(; low != high; ++ low) res = min(res, pair>{distance_powered(low->first, a[i]), pair{low->second, i}}); 24 | s.insert({a[i], i}); 25 | } 26 | return res; 27 | } 28 | ]]> 29 | 30 | find_a_closest_pair --> 31 | 32 | source.c++ --> 33 | 34 | -------------------------------------------------------------------------------- /Library/Geometry/Norm/find_a_furthest_pair_L1.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | pair> find_a_furthest_pair_L1(const vector> &a){ 8 | pair> res; 9 | auto cmp_xpy = [&](auto p, auto q)->bool{ return p.x + p.y < q.x + q.y; }; 10 | T imin = min_element(a.begin(), a.end(), cmp_xpy) - a.begin(); 11 | T imax = max_element(a.begin(), a.end(), cmp_xpy) - a.begin(); 12 | auto cmp_xmy = [&](auto p, auto q)->bool{ return p.x - p.y < q.x - q.y; }; 13 | T jmin = min_element(a.begin(), a.end(), cmp_xmy) - a.begin(); 14 | T jmax = max_element(a.begin(), a.end(), cmp_xmy) - a.begin(); 15 | return max( 16 | pair{a[imax].x + a[imax].y - a[imin].x - a[imin].y, pair{imin, imax}}, 17 | pair{a[jmax].x - a[jmax].y - a[jmin].x + a[jmin].y, pair{jmin, jmax}} 18 | ); 19 | } 20 | ]]> 21 | 22 | find_a_furthest_pair_L1 --> 23 | 24 | source.c++ --> 25 | 26 | -------------------------------------------------------------------------------- /Library/Geometry/Norm/find_a_furthest_pair_L2.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | pair> find_a_furthest_pair_L2(const vector> &a){ 8 | pair> res; 9 | for(auto p: (convex_polygon(a) - convex_polygon(a)).data) res = max(res, pair{p.squared_norm(), p}); 10 | vector order((int)a.size()); 11 | iota(order.begin(), order.end(), 0); 12 | sort(order.begin(), order.end(), [&](int i, int j){ return a[i] < a[j]; }); 13 | for(auto i: order){ 14 | auto q = res.second + a[i]; 15 | auto it = partition_point(order.begin(), order.end(), [&](int i){ return a[i] < q; }); 16 | if(it != order.end() && a[*it] == q) return {res.first, {i, *it}}; 17 | } 18 | assert(false); 19 | } 20 | ]]> 21 | 22 | find_a_furthest_pair_L2 --> 23 | 24 | source.c++ --> 25 | 26 | -------------------------------------------------------------------------------- /Library/Geometry/Norm/find_a_furthest_pair_Linf.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | pair> find_a_furthest_pair_Linf(const vector> &a){ 8 | T imin = min_element(a.begin(), a.end()) - a.begin(); 9 | T imax = max_element(a.begin(), a.end()) - a.begin(); 10 | auto cmp_y = [&](auto p, auto q)->bool{ return p.y < q.y; }; 11 | T jmin = min_element(a.begin(), a.end(), cmp_y) - a.begin(); 12 | T jmax = max_element(a.begin(), a.end(), cmp_y) - a.begin(); 13 | return max( 14 | pair{a[imax].x - a[imin].x, pair{imin, imax}}, 15 | pair{a[jmax].y - a[jmin].y, pair{jmin, jmax}} 16 | ); 17 | } 18 | ]]> 19 | 20 | find_a_furthest_pair_Linf --> 21 | 22 | source.c++ --> 23 | 24 | -------------------------------------------------------------------------------- /Library/Geometry/Norm/rectilinear_minimum_spanning_tree.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | vector> rectilinear_minimum_spanning_tree(vector> a){ 8 | int n = (int)a.size(); 9 | vector ind(n); 10 | iota(ind.begin(), ind.end(), 0); 11 | vector> edge; 12 | for(auto k = 0; k < 4; ++ k){ 13 | sort(ind.begin(), ind.end(), [&](int i, int j) { return a[i].x - a[j].x < a[j].y - a[i].y; }); 14 | map sweep; 15 | for(auto i: ind){ 16 | for(auto it = sweep.lower_bound(-a[i].y); it != sweep.end(); sweep.erase(it ++)){ 17 | int j = it->second; 18 | point d = a[i] - a[j]; 19 | if(d.y > d.x) break; 20 | edge.push_back({d.x + d.y, i, j}); 21 | } 22 | sweep.insert({-a[i].y, i}); 23 | } 24 | for(auto &p: a) if(k & 1) p.x = -p.x; else swap(p.x, p.y); 25 | } 26 | sort(edge.begin(), edge.end()); 27 | disjoint_set dsu(n); 28 | vector> res; 29 | for(auto [x, i, j]: edge) if(dsu.merge(i, j)) res.push_back({x, i, j}); 30 | return res; 31 | } 32 | ]]> 33 | 34 | rectilinear_minimum_spanning_tree --> 35 | 36 | source.c++ --> 37 | 38 | -------------------------------------------------------------------------------- /Library/Geometry/Polygon/point_in_polygon.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | bool point_in_polygon(const point &p, const vector> &poly, bool strict = true){ 6 | bool res = 0; 7 | for(auto i = 0, n = (int)poly.size(); i < n; ++ i){ 8 | point q = poly[(i + 1) % n]; 9 | if constexpr(is_floating_point_v){ 10 | if(line{poly[i], q}.distance_to_segment(p) < 1e-9) return !strict; 11 | } 12 | else if(line{poly[i], q}.on_segment(p)) return !strict; 13 | res ^= ((p.y < poly[i].y) - (p.y < q.y)) * doubled_signed_area(p, poly[i], q) > 0; 14 | } 15 | return res; 16 | } 17 | ]]> 18 | 19 | point_in_polygon --> 20 | 21 | source.c++ --> 22 | -------------------------------------------------------------------------------- /Library/Geometry/Polygon/polygon_cut.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | q 4 | // Requires point 5 | template 6 | vector> polygon_cut(const vector> &a, const point &p, const point &q){ 7 | vector> res; 8 | auto d = q - p; 9 | for(auto i = 0; i < (int)a.size(); ++ i){ 10 | auto cur = a[i], prev = i ? a[i - 1] : a.back(); 11 | bool side = doubled_signed_area(p, q, cur) > 0; 12 | if(side != (doubled_signed_area(p, q, prev) > 0)){ 13 | res.push_back(point(p) + 1.0 * (cur - p ^ prev - cur) / (d ^ prev - cur) * point(d)); 14 | } 15 | if(side) res.push_back(cur); 16 | } 17 | return res; 18 | } 19 | template 20 | vector> polygon_cutl(const vector> &a, const point &p, const point &q){ 21 | vector> res; 22 | auto d = q - p; 23 | for(auto i = 0; i < (int)a.size(); ++ i){ 24 | auto cur = a[i], prev = i ? a[i - 1] : a.back(); 25 | bool side = doubled_signed_area(p, q, cur) > 0; 26 | if(side != (doubled_signed_area(p, q, prev) > 0)){ 27 | res.push_back(point(p) + 1.0l * (cur - p ^ prev - cur) / (d ^ prev - cur) * point(d)); 28 | } 29 | if(side) res.push_back(cur); 30 | } 31 | return res; 32 | } 33 | ]]> 34 | 35 | polygon_cut --> 36 | 37 | source.c++ --> 38 | 39 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Clique/count_cliques.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | &adjm){ 6 | int n = (int)adjm.size(); 7 | assert(n <= 64); 8 | if(n <= 1) return n; 9 | int nl = n >> 1, nr = n - nl; 10 | static vector sum; 11 | sum.assign(1u << nr, 0); 12 | sum[0] = 1; 13 | static vector adjmask; 14 | adjmask.resize(1u << nr); 15 | adjmask[0] = (1u << nr) - 1; 16 | for(auto mask = 1u; mask < 1u << nr; ++ mask){ 17 | int u = __builtin_ctz(mask); 18 | adjmask[mask] = adjmask[mask ^ 1u << u] & (adjm[nl + u] >> nl | 1u << u); 19 | if((adjmask[mask] & mask) == mask) sum[mask] = 1; 20 | } 21 | for(auto u = 0; u < nr; ++ u) for(auto mask = 0; mask < 1u << nr; ++ mask) if(mask & 1u << u) sum[mask] += sum[mask ^ 1u << u]; 22 | adjmask.resize(1u << nl); 23 | adjmask[0] = (1ull << n) - 1; 24 | long long res = sum.back() - 1; 25 | for(auto mask = 1u; mask < 1u << nl; ++ mask){ 26 | int u = __builtin_ctz(mask); 27 | adjmask[mask] = adjmask[mask ^ 1u << u] & (adjm[u] | 1u << u); 28 | if((adjmask[mask] & mask) == mask) res += sum[adjmask[mask] >> nl]; 29 | } 30 | return res; 31 | } 32 | ]]> 33 | 34 | count_cliques --> 35 | 36 | source.c++ --> 37 | 38 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Clique/enumerate_maximal_cliques.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | &input_adjm, auto process_while){ 8 | int n = (int)input_adjm.size(); 9 | assert(n <= 64); 10 | if(n == 0) return; 11 | vector deg(n), order(n), pos(n); 12 | for(auto u = 0; u < n; ++ u) deg[u] = __builtin_popcountll(input_adjm[u]); 13 | iota(order.begin(), order.end(), 0); 14 | sort(order.begin(), order.end(), [&](int u, int v){ return deg[u] < deg[v]; }); 15 | for(auto t = 0; t < n; ++ t) pos[order[t]] = t; 16 | using ull = unsigned long long; 17 | vector adjm(n); 18 | for(auto u = 0; u < n; ++ u) for(auto v = u + 1; v < n; ++ v) if(input_adjm[u] & 1ull << v) adjm[pos[u]] ^= 1ull << pos[v], adjm[pos[v]] ^= 1ull << pos[u]; 19 | auto dfs = [&](auto self, ull r, ull p)->bool{ 20 | if(p == 0) return process_while(r); 21 | int u = __builtin_ctzll(p); 22 | ull c = p & ~adjm[u]; 23 | while(c){ 24 | u = __builtin_ctzll(c); 25 | ull umask = 1ull << u; 26 | r |= umask; 27 | if(!self(self, r, p & adjm[u])) return false; 28 | r &= ~umask; 29 | p &= ~umask; 30 | c ^= umask; 31 | } 32 | return true; 33 | }; 34 | dfs(dfs, 0, (1ull << n) - 1); 35 | } 36 | ]]> 37 | 38 | enumerate_maximal_cliques --> 39 | 40 | source.c++ --> 41 | 42 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Clique/enumerate_maximal_cliques_large.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | void enumerate_maximal_cliques_large(const vector> &input_adjm, auto process_while){ 8 | int n = (int)input_adjm.size(); 9 | if(n == 0) return; 10 | vector deg(n), order(n), pos(n); 11 | for(auto u = 0; u < n; ++ u) deg[u] = input_adjm[u].count(); 12 | iota(order.begin(), order.end(), 0); 13 | sort(order.begin(), order.end(), [&](int u, int v){ return deg[u] < deg[v]; }); 14 | for(auto t = 0; t < n; ++ t) pos[order[t]] = t; 15 | using bs = bitset; 16 | vector adjm(n); 17 | for(auto u = 0; u < n; ++ u) for(auto v = u + 1; v < n; ++ v) if(input_adjm[u][v]) adjm[pos[u]].set(pos[v]), adjm[pos[v]].set(pos[u]); 18 | auto dfs = [&](auto self, bs r, bs p)->bool{ 19 | if(p == 0) return process_while(r); 20 | int u = p._Find_first(); 21 | bs c = p & ~adjm[u]; 22 | while(c.count()){ 23 | u = c._Find_first(); 24 | bs umask; 25 | umask.set(u); 26 | r |= umask; 27 | if(!self(self, r, p & adjm[u])) return false; 28 | r &= ~umask; 29 | p &= ~umask; 30 | c ^= umask; 31 | } 32 | return true; 33 | }; 34 | bs p; 35 | for(auto u = 0; u < n; ++ u) p.set(u); 36 | dfs(dfs, {}, p); 37 | } 38 | ]]> 39 | 40 | enumerate_maximal_cliques_large --> 41 | 42 | source.c++ --> 43 | 44 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Connectivity/ear_decomposition.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | ear_decomposition --> 9 | 10 | source.c++ --> 11 | 12 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Forest_Algorithms/prufer_code.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > prufer_decode(vector code){ 5 | int n = (int)code.size() + 2; 6 | vector deg(n, 1); 7 | for(auto u: code){ 8 | assert(0 <= u && u < n); 9 | ++ deg[u]; 10 | } 11 | code.push_back(n - 1); 12 | vector> edge; 13 | for(auto i = 0, ptr = 0, leaf = 0; i < n - 1; ++ i){ 14 | while(leaf == n - 1 || deg[leaf] != 1) leaf = ++ ptr; 15 | edge.push_back({code[i], leaf}); 16 | -- deg[leaf]; 17 | -- deg[leaf = code[i]]; 18 | } 19 | return edge; 20 | } 21 | // O(n) 22 | vector prufer_encode(int n, const vector> &edge){ 23 | vector> adj(n); 24 | for(auto [u, v]: edge){ 25 | assert(0 <= min(u, v) && max(u, v) < n); 26 | adj[u].push_back(v), adj[v].push_back(u); 27 | } 28 | vector pv(n, -2), deg(n); 29 | auto dfs = [&](auto self, int u, int p)->void{ 30 | assert(pv[u] == -2); 31 | pv[u] = p; 32 | for(auto v: adj[u]) if(v != p){ 33 | ++ deg[u], ++ deg[v]; 34 | self(self, v, u); 35 | } 36 | }; 37 | dfs(dfs, n - 1, -1); 38 | for(auto u = 0; u < n; ++ u) assert(pv[u] != -2); 39 | vector code(n - 2); 40 | for(auto i = 0, ptr = 0, leaf = 0; i < n - 2; ++ i){ 41 | while(leaf == n - 1 || deg[leaf] != 1) leaf = ++ ptr; 42 | -- deg[leaf]; 43 | -- deg[code[i] = leaf = pv[leaf]]; 44 | } 45 | return code; 46 | } 47 | ]]> 48 | 49 | prufer_code --> 50 | 51 | source.c++ --> 52 | 53 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Forest_Algorithms/tree_diameter.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | struct tree_diameter{ 5 | int n; 6 | vector q, pe; 7 | vector dist; 8 | tree_diameter(int n): n(n), q(n), pe(n), dist(n){ 9 | assert(n >= 1); 10 | } 11 | // The connected component containing s must be a tree. 12 | // Returns {diamter, {starting vertex, list of edges}} 13 | // O(size(component)) 14 | // Requires graph 15 | template 16 | tuple> diameter(const graph &g, int s){ 17 | assert(g.n == n); 18 | auto bfs = [&](int s)->void{ 19 | q[0] = s; 20 | pe[s] = -1; 21 | dist[s] = 0; 22 | for(auto qbeg = 0, qend = 1; qbeg < qend; ++ qbeg){ 23 | int u = q[qbeg]; 24 | for(auto id: g.adj[u]){ 25 | if(g.ignore && g.ignore(id) || id == pe[u]) continue; 26 | int v = g(u, id); 27 | T w = g.edge[id].cost; 28 | q[qend ++] = v; 29 | pe[v] = id; 30 | dist[v] = dist[u] + w; 31 | } 32 | } 33 | }; 34 | bfs(s); 35 | int x = max_element(dist.begin(), dist.end()) - dist.begin(); 36 | bfs(x); 37 | int y = max_element(dist.begin(), dist.end()) - dist.begin(); 38 | vector diam; 39 | for(auto u = y; u != x; u = g(u, pe[u])) diam.push_back(pe[u]); 40 | diam.push_back(x); 41 | reverse(diam.begin(), diam.end()); 42 | return {dist[y], diam}; 43 | } 44 | }; 45 | ]]> 46 | 47 | tree_diameter --> 48 | 49 | source.c++ --> 50 | 51 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Forest_Algorithms/tree_hasher.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | struct tree_hasher{ 7 | mt19937 rng; 8 | vector order; 9 | vector base, hash; 10 | tree_hasher(): rng(chrono::high_resolution_clock::now().time_since_epoch().count()){} 11 | int attempt = 0; 12 | vector was; 13 | template 14 | void run(const graph &g, const vector &src = {0}, bool clear_order = true){ 15 | int n = g.n; 16 | ++ attempt; 17 | if(clear_order) order.clear(); 18 | while(base.size() < n) base.push_back(rng()); 19 | hash.resize(n); 20 | was.resize(n); 21 | auto dfs = [&](auto self, int u, int p)->int{ 22 | order.push_back(u); 23 | was[u] = attempt; 24 | hash[u] = 1; 25 | int d = 0; 26 | for(auto id: g.adj[u]){ 27 | if(g.ignore && g.ignore(id)) continue; 28 | int v = g(u, id); 29 | if(v == p) continue; 30 | d = max(d, self(self, v, u) + 1); 31 | } 32 | for(auto id: g.adj[u]){ 33 | if(g.ignore && g.ignore(id)) continue; 34 | int v = g(u, id); 35 | if(v == p) continue; 36 | hash[u] *= base[d] + hash[v]; 37 | } 38 | return d; 39 | }; 40 | for(auto s: src) if(was[s] != attempt) dfs(dfs, s, -1); 41 | } 42 | }; 43 | ]]> 44 | 45 | tree_hasher --> 46 | 47 | source.c++ --> 48 | 49 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Graph_Decomposition/decompose_into_paths_of_length_2.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 9 | void decompose_into_paths_of_length_2(const graph &g, auto process_p3, auto process_edge){ 10 | int n = g.n; 11 | vector depth(n, -1), used((int)g.edge.size()); 12 | auto recurse = [&](auto self, int u, int pe, int d)->bool{ 13 | int rem = -1; 14 | depth[u] = d; 15 | for(auto id: g.adj[u]){ 16 | if(id == pe || g.ignore && g.ignore(id)) continue; 17 | int v = g(u, id); 18 | if(~depth[v] && !used[id] || !~depth[v] && self(self, v, id, depth[u] + 1)){ 19 | used[id] = true; 20 | if(~rem){ 21 | process_p3(rem, u, id); 22 | rem = -1; 23 | } 24 | else rem = id; 25 | } 26 | } 27 | if(!~rem) return true; 28 | ~pe ? process_p3(pe, u, rem) : process_edge(rem); 29 | return false; 30 | }; 31 | for(auto u = 0; u < n; ++ u) if(!~depth[u]) recurse(recurse, u, -1, 0); 32 | } 33 | ]]> 34 | 35 | decompose_into_paths_of_length_2 --> 36 | 37 | source.c++ --> 38 | 39 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Graph_Readers/raw_read_digraph.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > n >> m; 5 | vector> adj(n); 6 | for(auto id = 0; id < m; ++ id){ 7 | int u, v; 8 | cin >> u >> v, -- u, -- v; 9 | adj[u].push_back(v); 10 | } 11 | ]]> 12 | 13 | raw_read_digraph --> 14 | 15 | source.c++ --> 16 | 17 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Graph_Readers/raw_read_graph.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > n >> m; 5 | vector> adj(n); 6 | for(auto id = 0; id < m; ++ id){ 7 | int u, v; 8 | cin >> u >> v, -- u, -- v; 9 | adj[u].push_back(v), adj[v].push_back(u); 10 | } 11 | ]]> 12 | 13 | raw_read_graph --> 14 | 15 | source.c++ --> 16 | 17 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Graph_Readers/raw_read_tree.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > n; 5 | vector> adj(n); 6 | for(auto id = 0; id < n - 1; ++ id){ 7 | int u, v; 8 | cin >> u >> v, -- u, -- v; 9 | adj[u].push_back(v), adj[v].push_back(u); 10 | } 11 | ]]> 12 | 13 | raw_read_tree --> 14 | 15 | source.c++ --> 16 | 17 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Graph_Readers/raw_read_wdigraph.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > n >> m; 5 | vector>> adj(n); 6 | for(auto id = 0; id < m; ++ id){ 7 | int u, v, w; 8 | cin >> u >> v >> w, -- u, -- v; 9 | adj[u].push_back({v, w}); 10 | } 11 | ]]> 12 | 13 | raw_read_wdigraph --> 14 | 15 | source.c++ --> 16 | 17 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Graph_Readers/raw_read_wgraph.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > n >> m; 5 | vector>> adj(n); 6 | for(auto id = 0; id < m; ++ id){ 7 | int u, v, w; 8 | cin >> u >> v >> w, -- u, -- v; 9 | adj[u].push_back({v, w}), adj[v].push_back({u, w}); 10 | } 11 | ]]> 12 | 13 | raw_read_wgraph --> 14 | 15 | source.c++ --> 16 | 17 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Graph_Readers/raw_read_wtree.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > n; 5 | vector>> adj(n); 6 | for(auto id = 0; id < n - 1; ++ id){ 7 | int u, v, w; 8 | cin >> u >> v >> w, -- u, -- v; 9 | adj[u].push_back({v, w}), adj[v].push_back({u, w}); 10 | } 11 | ]]> 12 | 13 | raw_read_wtree --> 14 | 15 | source.c++ --> 16 | 17 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Graph_Readers/read_digraph.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > n >> m; 5 | graph g(n); 6 | for(auto id = 0; id < m; ++ id){ 7 | int u, v; 8 | cin >> u >> v, -- u, -- v; 9 | g.orient(u, v, 1); 10 | } 11 | ]]> 12 | 13 | read_digraph --> 14 | 15 | source.c++ --> 16 | 17 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Graph_Readers/read_graph.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > n >> m; 5 | graph g(n); 6 | for(auto id = 0; id < m; ++ id){ 7 | int u, v; 8 | cin >> u >> v, -- u, -- v; 9 | g.link(u, v, 1); 10 | } 11 | ]]> 12 | 13 | read_graph --> 14 | 15 | source.c++ --> 16 | 17 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Graph_Readers/read_tree.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > n; 5 | graph g(n); 6 | for(auto id = 0; id < n - 1; ++ id){ 7 | int u, v; 8 | cin >> u >> v, -- u, -- v; 9 | g.link(u, v, 1); 10 | } 11 | ]]> 12 | 13 | read_tree --> 14 | 15 | source.c++ --> 16 | 17 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Graph_Readers/read_wdigraph.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > n >> m; 5 | graph g(n); 6 | for(auto id = 0; id < m; ++ id){ 7 | int u, v, w; 8 | cin >> u >> v >> w, -- u, -- v; 9 | g.orient(u, v, w); 10 | } 11 | ]]> 12 | 13 | read_wdigraph --> 14 | 15 | source.c++ --> 16 | 17 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Graph_Readers/read_wgraph.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > n >> m; 5 | graph g(n); 6 | for(auto id = 0; id < m; ++ id){ 7 | int u, v, w; 8 | cin >> u >> v >> w, -- u, -- v; 9 | g.link(u, v, w); 10 | } 11 | ]]> 12 | 13 | read_wgraph --> 14 | 15 | source.c++ --> 16 | 17 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Graph_Readers/read_wtree.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > n; 5 | graph g(n); 6 | for(auto id = 0; id < n - 1; ++ id){ 7 | int u, v, w; 8 | cin >> u >> v >> w, -- u, -- v; 9 | g.link(u, v, w); 10 | } 11 | ]]> 12 | 13 | read_wtree --> 14 | 15 | source.c++ --> 16 | 17 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Shortest_Path_Algorithms/Floyd_Warshall/floyd_warshall.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | struct floyd_warshall{ 5 | int n; 6 | vector> dist; 7 | floyd_warshall(int n): n(n), dist(n, vector(n)){ } 8 | // Assumes the graph has no negative cycle 9 | // O(|V|^3) 10 | template 11 | void run(const vector> &adjm){ 12 | assert(!n && adjm.empty() || n == (int)adjm.size() && n == (int)adjm[0].size()); 13 | for(auto u = 0; u < n; ++ u) for(auto v = 0; v < n; ++ v) dist[u][v] = adjm[u][v]; 14 | for(auto w = 0; w < n; ++ w) for(auto u = 0; u < n; ++ u) for(auto v = 0; v < n; ++ v) dist[u][v] = min(dist[u][v], dist[u][w] + dist[w][v]); 15 | } 16 | template 17 | void run(const vector> &edge, bool directed = false){ 18 | vector> adjm(n, vector(n, numeric_limits::max() / 2)); 19 | for(auto u = 0; u < n; ++ u) adjm[u][u] = 0; 20 | for(auto [u, v, w]: edge){ 21 | adjm[u][v] = min(adjm[u][v], w); 22 | if(!directed) adjm[v][u] = adjm[u][v]; 23 | } 24 | run(adjm); 25 | } 26 | // Requires graph 27 | template 28 | void run(const G &g, bool directed = false){ 29 | vector> adjm(n, vector(n, numeric_limits::max() / 2)); 30 | for(auto u = 0; u < n; ++ u) adjm[u][u] = 0; 31 | for(auto [u, v, w]: g.edge){ 32 | adjm[u][v] = min(adjm[u][v], w); 33 | if(!directed) adjm[v][u] = adjm[u][v]; 34 | } 35 | run(adjm); 36 | } 37 | }; 38 | ]]> 39 | 40 | floyd_warshall --> 41 | 42 | source.c++ --> 43 | 44 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Spanning_Forest_Algorithms/complement_spanning_forest.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | vector> complement_spanning_forest(const graph &g){ 6 | int n = g.n; 7 | auto adj = g.get_adjacency_list(); 8 | for(auto &a: adj) sort(a.begin(), a.end()); 9 | set alive; 10 | for(auto u = 0; u < n; ++ u) alive.insert(u); 11 | vector> res; 12 | while(!alive.empty()){ 13 | int u = *alive.begin(); alive.erase(alive.begin()); 14 | deque dq{u}; 15 | while(!dq.empty()){ 16 | int v = dq.front(); dq.pop_front(); 17 | for(auto it = alive.begin(); it != alive.end(); ){ 18 | if(auto it2 = lower_bound(adj[v].begin(), adj[v].end(), *it); it2 != adj[v].end() && *it2 == *it) ++ it; 19 | else dq.push_back(*it), res.push_back({u, *it}), it = alive.erase(it); 20 | } 21 | } 22 | } 23 | return res; 24 | } 25 | ]]> 26 | 27 | complement_spanning_forest --> 28 | 29 | source.c++ --> 30 | 31 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Spanning_Forest_Algorithms/count_spanning_forest.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | T count_spanning_forest(const graph &g){ 5 | int n = g.n; 6 | vector vis(n); 7 | T res = 1; 8 | for(auto u = 0; u < n; ++ u){ 9 | if(vis[u]) continue; 10 | vector comp; 11 | auto dfs = [&](auto self, int u)->void{ 12 | vis[u] = true; 13 | comp.push_back(u); 14 | for(auto id: g.adj[u]){ 15 | if(g.ignore && g.ignore(id)) continue; 16 | int v = g(u, id); 17 | if(!vis[v]) self(self, v); 18 | } 19 | }; 20 | dfs(dfs, u); 21 | sort(comp.begin(), comp.end()); 22 | vector> mat((int)comp.size() - 1, vector((int)comp.size() - 1)); 23 | for(auto i = 0; i < (int)comp.size(); ++ i){ 24 | int u = comp[i]; 25 | for(auto id: g.adj[u]){ 26 | if(g.ignore && g.ignore(id)) continue; 27 | int v = g(u, id); 28 | if(u < v){ 29 | int j = lower_bound(comp.begin(), comp.end(), v) - comp.begin(); 30 | ++ mat[i][i]; 31 | if(j < (int)comp.size() - 1){ 32 | ++ mat[j][j]; 33 | mat[i][j] -= g.edge[id].cost; 34 | mat[j][i] -= g.edge[id].cost; 35 | } 36 | } 37 | } 38 | } 39 | res *= determinant_integral(mat); 40 | } 41 | return res; 42 | } 43 | ]]> 44 | 45 | count_spanning_forest --> 46 | 47 | source.c++ --> 48 | 49 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Spanning_Forest_Algorithms/minimum_spanning_forest.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | vector minimum_spanning_forest(const G &g){ 6 | vector order(g.edge.size()); 7 | iota(order.begin(), order.end(), 0); 8 | if(g.ignore) order.erase(remove_if(order.begin(), order.end(), [&](int id){ return g.ignore(id); }), order.end()); 9 | sort(order.begin(), order.end(), [&](int i, int j){ return g.edge[i].cost < g.edge[j].cost; }); 10 | disjoint_set dsu(g.n); 11 | vector res; 12 | for(auto id: order){ 13 | auto &e = g.edge[id]; 14 | if(dsu.merge(e.from, e.to)) res.push_back(id); 15 | } 16 | return res; 17 | } 18 | template 19 | vector minimum_spanning_forest(int n, const vector> &edge){ 20 | vector order(edge.size()); 21 | iota(order.begin(), order.end(), 0); 22 | sort(order.begin(), order.end(), [&](int i, int j){ return get<2>(edge[i]) < get<2>(edge[j]); }); 23 | disjoint_set dsu(n); 24 | vector res; 25 | for(auto id: order){ 26 | auto &e = edge[id]; 27 | if(dsu.merge(get<0>(e), get<1>(e))) res.push_back(id); 28 | } 29 | return res; 30 | } 31 | ]]> 32 | 33 | minimum_spanning_forest --> 34 | 35 | source.c++ --> 36 | 37 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Special_Graphs/recognize_chordal_graphs.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | = 4} 4 | // O(n + m) 5 | // Requires graph and lexicographical_bfs_forest 6 | template 7 | optional> recognize_chordal_graphs(const graph &g){ 8 | int n = g.n; 9 | vector> adj(n); 10 | for(auto u = 0; u < n; ++ u) for(auto id: g.adj[u]) if(!g.ignore || !g.ignore(id)) adj[g(u, id)].push_back(u); 11 | lexicographical_bfs_forest lbf(n); 12 | lbf.bfs(g); 13 | for(auto u = 0; u < n; ++ u){ 14 | if(!~lbf.latest[u]) continue; 15 | int v = lbf.latest[u]; 16 | for(auto w: adj[u]){ 17 | if(v != w && lbf.pos[w] < lbf.pos[u] && !binary_search(adj[v].begin(), adj[v].end(), w)){ 18 | vector vis(n), par(n, -1); 19 | vis[w] = true; 20 | deque dq{w}; 21 | while(!dq.empty()){ 22 | int x = dq.front(); dq.pop_front(); 23 | for(auto y: adj[x]){ 24 | if(vis[y] || y == u || y != v && binary_search(adj[u].begin(), adj[u].end(), y)) continue; 25 | vis[y] = true; 26 | dq.push_back(y); 27 | par[y] = x; 28 | } 29 | } 30 | vector cycle{w, u}; 31 | for(auto x = v; x != w; x = par[x]) cycle.push_back(x); 32 | return {}; 33 | } 34 | } 35 | } 36 | auto order = lbf.order; 37 | reverse(order.begin(), order.end()); 38 | return order; 39 | } 40 | ]]> 41 | 42 | recognize_chordal_graphs --> 43 | 44 | source.c++ --> 45 | 46 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Sqrt_Trick/count_4_cycles.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | T count_4_cycles(int n, const vector> &edge){ 6 | int m = (int)edge.size(); 7 | vector deg(n), order, pos(n); 8 | vector> appear(m + 1), adj(n); 9 | for(auto [u, v]: edge) ++ deg[u], ++ deg[v]; 10 | for(auto u = 0; u < n; ++ u) appear[deg[u]].push_back(u); 11 | for(auto d = m; d >= 0; -- d) order.insert(order.end(), appear[d].begin(), appear[d].end()); 12 | for(auto i = 0; i < n; ++ i) pos[order[i]] = i; 13 | for(auto i = 0; i < m; ++ i){ 14 | int u = pos[edge[i][0]], v = pos[edge[i][1]]; 15 | adj[u].push_back(v), adj[v].push_back(u); 16 | } 17 | T res = 0; 18 | vector cnt(n); 19 | for(auto u = 0; u < n; ++ u){ 20 | for(auto v: adj[u]) if(u < v) for(auto w: adj[v]) if(u < w) cnt[w] = 0; 21 | for(auto v: adj[u]) if(u < v) for(auto w: adj[v]) if(u < w) res += cnt[w] ++; 22 | } 23 | return res; 24 | } 25 | ]]> 26 | 27 | count_4_cycles --> 28 | 29 | source.c++ --> 30 | 31 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Sqrt_Trick/find_3_cycles.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > &edge, auto process){ 6 | int m = (int)edge.size(); 7 | vector deg(n), order, pos(n); 8 | vector> appear(m + 1), adj(n), found(n); 9 | for(auto [u, v]: edge) ++ deg[u], ++ deg[v]; 10 | for(auto u = 0; u < n; ++ u) appear[deg[u]].push_back(u); 11 | for(auto d = m; d >= 0; -- d) order.insert(order.end(), appear[d].begin(), appear[d].end()); 12 | for(auto i = 0; i < n; ++ i) pos[order[i]] = i; 13 | for(auto i = 0; i < m; ++ i){ 14 | int u = pos[edge[i][0]], v = pos[edge[i][1]]; 15 | adj[u].push_back(v), adj[v].push_back(u); 16 | } 17 | for(auto u = 0; u < n; ++ u) for(auto v: adj[u]) if(u < v){ 18 | for(auto i = 0, j = 0; i < (int)found[u].size() && j < (int)found[v].size(); ){ 19 | if(found[u][i] == found[v][j]){ 20 | process(order[u], order[v], order[found[u][i]]); 21 | ++ i, ++ j; 22 | } 23 | else if(found[u][i] < found[v][j]) ++ i; 24 | else ++ j; 25 | } 26 | found[v].push_back(u); 27 | } 28 | } 29 | ]]> 30 | 31 | find_3_cycles --> 32 | 33 | source.c++ --> 34 | 35 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Sqrt_Trick/find_4_cycles.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > &edge, auto process, int th = 1){ 5 | int m = (int)edge.size(); 6 | vector deg(n), order, pos(n); 7 | vector> appear(m + 1), adj(n), found(n); 8 | for(auto [u, v]: edge) ++ deg[u], ++ deg[v]; 9 | for(auto u = 0; u < n; ++ u) appear[deg[u]].push_back(u); 10 | for(auto d = m; d >= 0; -- d) order.insert(order.end(), appear[d].begin(), appear[d].end()); 11 | for(auto i = 0; i < n; ++ i) pos[order[i]] = i; 12 | for(auto i = 0; i < m; ++ i){ 13 | int u = pos[edge[i][0]], v = pos[edge[i][1]]; 14 | adj[u].push_back(v), adj[v].push_back(u); 15 | } 16 | for(auto u = 0; u < n; ++ u){ 17 | for(auto v: adj[u]) if(u < v) for(auto w: adj[v]) if(u < w) found[w].clear(); 18 | for(auto v: adj[u]) if(u < v) for(auto w: adj[v]) if(u < w){ 19 | for(auto x: found[w]){ 20 | if(!(th --)) return; 21 | process(order[u], order[v], order[w], order[x]); 22 | } 23 | found[w].push_back(v); 24 | } 25 | } 26 | } 27 | ]]> 28 | 29 | find_4_cycles --> 30 | 31 | source.c++ --> 32 | 33 | -------------------------------------------------------------------------------- /Library/Graph_Theory/Tree_Decomposition/tree_decomposition_chordal_graph.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | pair>, vector>> // bags, edges 6 | tree_decomposition_chordal_graph(const graph &g){ 7 | int n = g.n; 8 | auto orderptr = recognize_chordal_graphs(g); 9 | assert(orderptr); 10 | auto order = *orderptr; 11 | vector pos(n); 12 | for(auto i = 0; i < n; ++ i) pos[order[i]] = i; 13 | vector> bags; 14 | vector> edge; 15 | vector label(n, -1); 16 | reverse(order.begin(), order.end()); 17 | for(auto u: order){ 18 | int i = (int)bags.size(); 19 | label[u] = i; 20 | vector bag{u}; 21 | for(auto id: g.adj[u]){ 22 | if(g.ignore && g.ignore(id)) continue; 23 | int v = g(u, id); 24 | if(pos[u] < pos[v]) bag.push_back(v); 25 | } 26 | if((int)bag.size() >= 2) edge.push_back({i, label[*min_element(bag.begin() + 1, bag.end(), [&](int u, int v){ return pos[u] < pos[v]; })]}); 27 | sort(bag.begin(), bag.end()); 28 | bags.push_back(bag); 29 | } 30 | return {bags, edge}; 31 | } 32 | ]]> 33 | 34 | tree_decomposition_chordal_graph --> 35 | 36 | source.c++ --> 37 | 38 | -------------------------------------------------------------------------------- /Library/Graph_Theory/edge_path_into_vertex_path.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | vector edge_path_into_vertex_path(const graph &g, int s, const vector &edge_path){ 6 | vector vertex_path{s}; 7 | for(auto id: edge_path){ 8 | auto &e = g.edge[id]; 9 | assert(e.from == vertex_path.back() || e.to == vertex_path.back()); 10 | vertex_path.push_back(vertex_path.back() ^ e.from ^ e.to); 11 | } 12 | return vertex_path; 13 | } 14 | ]]> 15 | 16 | edge_path_into_vertex_path --> 17 | 18 | source.c++ --> 19 | 20 | -------------------------------------------------------------------------------- /Library/Graph_Theory/find_all_cycle_masks.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 8 | void find_all_cycle_masks(const graph &g, auto act_while){ 9 | int n = g.n; 10 | assert(n <= 30); 11 | vector adjmask(n), checked(1 << n), dp(1 << n); 12 | for(auto u = 0; u < n; ++ u) for(auto id: g.adj[u]){ 13 | if(g.ignore && g.ignore(id)) continue; 14 | adjmask[u] |= 1 << g(u, id); 15 | } 16 | for(auto s = n - 1; s >= 0; -- s){ 17 | fill(dp.begin(), dp.begin() + (1 << s + 1), 0); 18 | dp[1 << s] = 1 << s; 19 | for(auto mask = 1; mask < 1 << s + 1; ++ mask){ 20 | int neighbor = 0; 21 | for(auto u = 0; u <= s; ++ u) if(dp[mask] & 1 << u){ 22 | if(!checked[mask] && adjmask[u] & 1 << s){ 23 | checked[mask] = true; 24 | if(!act_while(mask, u, dp, adjmask)) return; 25 | } 26 | neighbor |= adjmask[u]; 27 | } 28 | neighbor &= ~mask; 29 | for(auto u = 0; u <= s; ++ u) if(neighbor & 1 << u) dp[mask | 1 << u] |= 1 << u; 30 | } 31 | } 32 | } 33 | ]]> 34 | 35 | find_all_cycle_masks --> 36 | 37 | source.c++ --> 38 | 39 | -------------------------------------------------------------------------------- /Library/Grid/direction_vectors.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > dr2{{1, 0}, {0, 1}}; 5 | vector> dr4{{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; 6 | vector> dr4diag{{1, 1}, {-1, 1}, {-1, -1}, {1, -1}}; 7 | vector> dr8{{1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}, {0, -1}, {1, -1}}; 8 | vector> drk{{2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}, {-1, -2}, {1, -2}, {2, -1}}; 9 | vector> generate(int low, int high){ 10 | assert(0 <= low && low <= high); 11 | int th = sqrt(high) + 1; 12 | vector> dr; 13 | for(auto x = -th; x <= th; ++ x) for(auto y = -th; y <= th; ++ y) if(auto d = x * x + y * y; low <= d && d <= high) dr.push_back({x, y}); 14 | return dr; 15 | } 16 | } 17 | ]]> 18 | 19 | direction_vectors --> 20 | 21 | source.c++ --> 22 | 23 | -------------------------------------------------------------------------------- /Library/Initialize/__initialize.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | // Temp fix for gcc13 global pragma 4 | // #pragma GCC target("avx2,bmi2,popcnt,lzcnt") 5 | // #pragma GCC optimize("O3,unroll-loops") 6 | #include 7 | // #include 8 | using namespace std; 9 | #if __cplusplus >= 202002L 10 | using namespace numbers; 11 | #endif 12 | #ifdef LOCAL 13 | #include "Debug.h" 14 | #else 15 | #define debug_endl() 42 16 | #define debug(...) 42 17 | #define debug2(...) 42 18 | #define debug_bin(...) 42 19 | #endif 20 | 21 | 22 | 23 | int main(){ 24 | cin.tie(0)->sync_with_stdio(0); 25 | cin.exceptions(ios::badbit | ios::failbit); 26 | $0 27 | return 0; 28 | } 29 | 30 | /* 31 | 32 | */ 33 | ]]> 34 | 35 | initialize 36 | 37 | source.c++ 38 | -------------------------------------------------------------------------------- /Library/Initialize/__mhc_init.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | // Temp fix for gcc13 global pragma 4 | // #pragma GCC target("avx2,bmi2,popcnt,lzcnt") 5 | // #pragma GCC optimize("O3,unroll-loops") 6 | #include 7 | // #include 8 | using namespace std; 9 | using namespace numbers; 10 | #ifdef LOCAL 11 | #include "Debug.h" 12 | #else 13 | #define debug_endl() 42 14 | #define debug(...) 42 15 | #define debug2(...) 42 16 | #define debug_bin(...) 42 17 | #endif 18 | 19 | 20 | 21 | int main(){ 22 | cin.tie(0)->sync_with_stdio(0); 23 | cin.exceptions(ios::badbit | ios::failbit); 24 | auto solve_testcase = [&](auto testcase_id)->int{ 25 | $0 26 | return 0; 27 | }; 28 | int testcase_count; 29 | cin >> testcase_count; 30 | for(auto testcase_id = 0; testcase_id < testcase_count; ++ testcase_id){ 31 | cout << "Case #" << testcase_id + 1 << ": "; 32 | solve_testcase(testcase_id); 33 | } 34 | return 0; 35 | } 36 | 37 | /* 38 | 39 | */ 40 | 41 | //////////////////////////////////////////////////////////////////////////////////////// 42 | // // 43 | // Coded by Aeren // 44 | // // 45 | //////////////////////////////////////////////////////////////////////////////////////// 46 | ]]> 47 | 48 | mhc_init --> 49 | 50 | source.c++ --> 51 | 52 | -------------------------------------------------------------------------------- /Library/Initialize/__tc_init.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | // Temp fix for gcc13 global pragma 4 | // #pragma GCC target("avx2,bmi2,popcnt,lzcnt") 5 | // #pragma GCC optimize("O3,unroll-loops") 6 | #include 7 | // #include 8 | using namespace std; 9 | #if __cplusplus >= 202002L 10 | using namespace numbers; 11 | #endif 12 | #ifdef LOCAL 13 | #include "Debug.h" 14 | #else 15 | #define debug_endl() 42 16 | #define debug(...) 42 17 | #define debug2(...) 42 18 | #define debug_bin(...) 42 19 | #endif 20 | 21 | 22 | 23 | int main(){ 24 | cin.tie(0)->sync_with_stdio(0); 25 | cin.exceptions(ios::badbit | ios::failbit); 26 | auto solve_testcase = [&](auto testcase_id)->int{ 27 | $0 28 | return 0; 29 | }; 30 | int testcase_count; 31 | cin >> testcase_count; 32 | for(auto testcase_id = 0; testcase_id < testcase_count; ++ testcase_id){ 33 | solve_testcase(testcase_id); 34 | } 35 | return 0; 36 | } 37 | 38 | /* 39 | 40 | */ 41 | ]]> 42 | 43 | tc_init 44 | 45 | source.c++ 46 | 47 | -------------------------------------------------------------------------------- /Library/Initialize/__tc_init_python.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | tc_init 13 | 14 | source.python 15 | 16 | -------------------------------------------------------------------------------- /Library/Initialize/__testlib_init.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | // Temp fix for gcc13 global pragma 4 | // #pragma GCC target("avx2,bmi2,popcnt,lzcnt") 5 | // #pragma GCC optimize("O3,unroll-loops") 6 | #include 7 | // #include 8 | #include "testlib.h" 9 | using namespace std; 10 | using namespace numbers; 11 | #ifdef LOCAL 12 | #include "Debug.h" 13 | #else 14 | #define debug_endl() 42 15 | #define debug(...) 42 16 | #define debug2(...) 42 17 | #define debug_bin(...) 42 18 | #endif 19 | 20 | 21 | 22 | int main(int argc, char *argv[]){ 23 | registerGen(argc, argv, 1); // For generators 24 | // registerValidation(argc, argv); // For validators 25 | // registerTestlibCmd(argc, argv); // For checkers 26 | // registerInteraction(argc, argv); // For interactives 27 | $0 28 | return 0; 29 | } 30 | 31 | /* 32 | 33 | */ 34 | 35 | //////////////////////////////////////////////////////////////////////////////////////// 36 | // // 37 | // Coded by Aeren // 38 | // // 39 | //////////////////////////////////////////////////////////////////////////////////////// 40 | ]]> 41 | 42 | testlib_init --> 43 | 44 | source.c++ --> 45 | 46 | -------------------------------------------------------------------------------- /Library/Linear_Algebra/Linear_Recurrence_Solver/fibonacci.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | T fibonacci(auto i){ 6 | assert(i >= 0); 7 | if(i <= 10){ 8 | if(i < 2) return i; 9 | T a = 0, b = 1; 10 | for(; i >= 2; -- i){ 11 | swap(a, b); 12 | b += a; 13 | } 14 | return b; 15 | } 16 | T a = i % 2, b = 1 - 2 * (i % 2), c = 3; 17 | for(i >>= 1; i >= 2; i >>= 1){ 18 | if(i % 2 == 0) b = a + b * c; 19 | else a = b + a * c; 20 | c = c * c - 2; 21 | } 22 | return b + a * c; 23 | } 24 | ]]> 25 | 26 | fibonacci --> 27 | 28 | source.c++ --> 29 | 30 | -------------------------------------------------------------------------------- /Library/Linear_Algebra/Matrix/characteristic_polynomial_commutative_ring.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 8 | vector characteristic_polynomial_commutative_ring(const vector> &M, T T_id_add = 0, T T_id_mul = 1, bool flip = false){ 9 | if(M.empty()) return {T_id_mul}; 10 | int n = (int)M.size(); 11 | assert((int)M[0].size() == n); 12 | vector> dp(n, vector(n, T_id_add)); 13 | auto dp_next = dp; 14 | vector res(n + 1, T_id_add); 15 | res[n] = n & 1 ? -T_id_mul : T_id_mul; 16 | for(auto i = 0; i < n; ++ i) dp[i][i] = n & 1 ? T_id_mul : -T_id_mul; 17 | for(auto l = 0; ; ++ l){ 18 | for(auto i = 0; i < n; ++ i) for(auto j = i; j < n; ++ j) res[n - 1 - l] += dp[i][j] * M[j][i]; 19 | if(l == n - 1) break; 20 | for(auto &r: dp_next) fill(r.begin(), r.end(), T_id_add); 21 | for(auto i = 0; i < n; ++ i) for(auto j = 0; j <= i; ++ j){ 22 | T x = dp[j][i]; 23 | for(auto k = j + 1; k < n; ++ k) dp_next[j][k] += x * M[i][k]; 24 | if(j + 1 < n) dp_next[j + 1][j + 1] -= dp[j][i] * M[i][j]; 25 | } 26 | for(auto i = 0; i < n - 1; ++ i) dp_next[i + 1][i + 1] += dp_next[i][i]; 27 | swap(dp, dp_next); 28 | } 29 | if(!flip && n & 1) for(auto &x: res) x = -x; 30 | return res; 31 | } 32 | ]]> 33 | 34 | characteristic_polynomial_commutative_ring --> 35 | 36 | source.c++ --> 37 | 38 | -------------------------------------------------------------------------------- /Library/Linear_Algebra/Matrix/determinant_commutative_ring.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 8 | T determinant_commutative_ring(const vector> &M, T T_id_add = 0, T T_id_mul = 1){ 9 | if(M.empty()) return {T_id_mul}; 10 | int n = (int)M.size(); 11 | assert((int)M[0].size() == n); 12 | vector> dp(n, vector(n, T_id_add)); 13 | auto dp_next = dp; 14 | for(auto i = 0; i < n; ++ i) dp[i][i] = n & 1 ? T_id_mul : -T_id_mul; 15 | for(auto l = 0; l < n - 1; ++ l){ 16 | for(auto &r: dp_next) fill(r.begin(), r.end(), T_id_add); 17 | for(auto i = 0; i < n; ++ i) for(auto j = 0; j <= i; ++ j){ 18 | T x = dp[j][i]; 19 | for(auto k = j + 1; k < n; ++ k) dp_next[j][k] += x * M[i][k]; 20 | if(j + 1 < n) dp_next[j + 1][j + 1] -= dp[j][i] * M[i][j]; 21 | } 22 | for(auto i = 0; i < n - 1; ++ i) dp_next[i + 1][i + 1] += dp_next[i][i]; 23 | swap(dp, dp_next); 24 | } 25 | T res = T_id_add; 26 | for(auto i = 0; i < n; ++ i) for(auto j = i; j < n; ++ j) res += dp[i][j] * M[j][i]; 27 | return res; 28 | } 29 | ]]> 30 | 31 | determinant_commutative_ring --> 32 | 33 | source.c++ --> 34 | 35 | -------------------------------------------------------------------------------- /Library/Linear_Algebra/Matrix/sparse_determinant.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | // calculate the determinant of the sparse matrix 9 | T sparse_determinant(auto &&rng, int n, vector> a){ 10 | vector D(n); 11 | T det_D = 1; 12 | for(auto &x: D){ 13 | do x = rng(); while(!x); 14 | det_D *= x; 15 | } 16 | for(auto &[i, j, val]: a) val *= D[i]; 17 | T det = sparse_minimal_polynomial(rng, n, a)[0] * (n & 1 ? -1 : 1); 18 | return det / det_D; 19 | } 20 | ]]> 21 | 22 | sparse_determinant --> 23 | 24 | source.c++ --> 25 | 26 | -------------------------------------------------------------------------------- /Library/Linear_Algebra/Matrix/sparse_minimal_polynomial.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 9 | vector sparse_minimal_polynomial(auto &&rng, int n, const vector> &a){ 10 | vector v(n), p(n), s; 11 | generate(v.begin(), v.end(), rng), generate(p.begin(), p.end(), rng); 12 | for(auto rep = 0; rep < n << 1; ++ rep){ 13 | T x = 0; 14 | for(auto i = 0; i < n; ++ i) x += v[i] * p[i]; 15 | s.push_back(x); 16 | vector p_next(n); 17 | for(auto [i, j, val]: a) p_next[i] += val * p[j]; 18 | swap(p, p_next); 19 | } 20 | auto poly = linear_recurrence_solver(s).coef; 21 | for(auto &x: poly) x = -x; 22 | poly.push_back(1); 23 | return poly; 24 | } 25 | ]]> 26 | 27 | sparse_minimal_polynomial --> 28 | 29 | source.c++ --> 30 | 31 | -------------------------------------------------------------------------------- /Library/Linear_Algebra/Matrix/tridiagonal_matrix_determinant.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | T tridiagonal_matrix_determinant(const vector &diag, const vector &sup, const vector &sub){ 6 | int n = (int)diag.size(); 7 | assert((int)sup.size() == n - 1 && (int)sub.size() == n - 1); 8 | T a = 1, b = diag[0]; 9 | for(auto i = 1; i < n; ++ i) tie(a, b) = pair{b, diag[i] * b - sup[i - 1] * sub[i - 1] * a}; 10 | return b; 11 | } 12 | ]]> 13 | 14 | tridiagonal_matrix_determinant --> 15 | 16 | source.c++ --> 17 | 18 | -------------------------------------------------------------------------------- /Library/Linear_Algebra/Matrix/tridiagonal_matrix_equation_solver.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | vector tridiagonal_matrix_equation_solver(vector diag, const vector& sup, 7 | const vector& sub, vector b){ 8 | int n = (int)b.size(); 9 | vector tr(n); 10 | for(auto i = 0; i < n - 1; ++ i){ 11 | if(-T(1e-9) <= diag[i] && diag[i] <= T(1e-9)){ 12 | b[i + 1] -= b[i] * diag[i + 1] / sup[i]; 13 | if(i + 2 < n) b[i + 2] -= b[i] * sub[i + 1] / sup[i]; 14 | diag[i + 1] = sub[i]; 15 | tr[++ i] = 1; 16 | } 17 | else{ 18 | diag[i + 1] -= sup[i] * sub[i] / diag[i]; 19 | b[i+1] -= b[i] * sub[i] / diag[i]; 20 | } 21 | } 22 | for(auto i = n; i --; ){ 23 | if(tr[i]){ 24 | swap(b[i], b[i - 1]); 25 | diag[i - 1] = diag[i]; 26 | b[i] /= sup[i - 1]; 27 | } 28 | else{ 29 | b[i] /= diag[i]; 30 | if(i) b[i - 1] -= b[i] * sup[i - 1]; 31 | } 32 | } 33 | return b; 34 | } 35 | ]]> 36 | 37 | tridiagonal_matrix_equation_solver --> 38 | 39 | source.c++ --> 40 | 41 | -------------------------------------------------------------------------------- /Library/Miscellaneous/bitset64.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #pragma push_macro("__SIZEOF_LONG__") 10 | #pragma push_macro("__cplusplus") 11 | #undef __SIZEOF_LONG__ 12 | #define __SIZEOF_LONG__ __SIZEOF_LONG_LONG__ 13 | #define unsigned unsigned long 14 | #undef __cplusplus 15 | #define __cplusplus 201102L 16 | 17 | #define __builtin_popcountl __builtin_popcountll 18 | #define __builtin_ctzl __builtin_ctzll 19 | 20 | #include 21 | 22 | #pragma pop_macro("__cplusplus") 23 | #pragma pop_macro("__SIZEOF_LONG__") 24 | #undef unsigned 25 | #undef __builtin_popcountl 26 | #undef __builtin_ctzl 27 | ]]> 28 | 29 | bitset64 --> 30 | 31 | source.c++ --> 32 | 33 | -------------------------------------------------------------------------------- /Library/Miscellaneous/de_bruijn_bit_magic.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > 27]; 9 | } // 0x077CB531U = B(2,5) = 0000 0111 0111 1100 1011 0101 0011 0001; 10 | uint32_t _fastlg(uint32_t x){ 11 | x |= x >> 1, x |= x >> 2, x |= x >> 4, x |= x >> 8, x |= x >> 16; 12 | return x - (x >> 1); 13 | } 14 | unsigned long long _fastlgl(unsigned long long x){ 15 | x |= x >> 1, x |= x >> 2, x |= x >> 4, x |= x >> 8, x |= x >> 16, x |= x >> 32; 16 | return x - (x >> 1); 17 | } 18 | int _msp(unsigned int x){ // most significant position 19 | return DeBruijnPosition[_fastlg(x) * 0x077CB531u >> 27]; 20 | } // 0x077CB531U = B(2,5) = 0000 0111 0111 1100 1011 0101 0011 0001; 21 | ]]> 22 | 23 | de_bruijn_bit_magic --> 24 | 25 | source.c++ --> 26 | 27 | -------------------------------------------------------------------------------- /Library/Miscellaneous/floored_root.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | pow[65]; 6 | floored_root(){ 7 | for(auto t = 2u; t < 1 << 16; ++ t){ 8 | unsigned long long s = t * t; 9 | s = s * s; 10 | for(auto k = 4; ; ++ k){ 11 | pow[k].push_back(s); 12 | if(__builtin_umulll_overflow(s, t, &s)) break; 13 | } 14 | } 15 | } 16 | unsigned long long sqrt(unsigned long long n) const{ 17 | unsigned long long x = std::sqrt(n); 18 | return x * x > n ? x - 1 : x; 19 | } 20 | unsigned long long cbrt(unsigned long long n) const{ 21 | unsigned long long x = 0, y = 0; 22 | for(auto s = 63; s >= 0; s -= 3){ 23 | x <<= 1; 24 | y = 3 * x * (x + 1) + 1; 25 | if(y <= (n >> s)) n -= y << s, ++ x; 26 | } 27 | return x; 28 | } 29 | unsigned long long operator()(unsigned long long n, int k) const{ 30 | assert(1 <= k && k <= 64); 31 | if(k == 1 || n == 0) return n; 32 | if(k == 2) return sqrt(n); 33 | if(k == 3) return cbrt(n); 34 | return upper_bound(pow[k].begin(), pow[k].end(), n) - pow[k].begin() + 1; 35 | } 36 | }; 37 | ]]> 38 | 39 | floored_root --> 40 | 41 | source.c++ --> 42 | 43 | -------------------------------------------------------------------------------- /Library/Miscellaneous/hilbert_curve_2d.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | struct hilbert_curve_2d{ 6 | int level; 7 | T size; 8 | hilbert_curve_2d(int level = 0): level(level), size(T(1) << level){ } 9 | void rotate(T size, T &x, T &y, bool rx, bool ry) const{ 10 | if(!ry){ 11 | if(rx) x ^= size - 1, y ^= size - 1; 12 | swap(x, y); 13 | } 14 | } 15 | T_large order(T x, T y) const{ 16 | assert(0 <= x && x < size && 0 <= y && y < size); 17 | T_large d = 0; 18 | for(auto s = size >> 1; s; s >>= 1){ 19 | bool rx = x & s, ry = y & s; 20 | d = d << 2 | 3 * rx ^ ry; 21 | rotate(size, x, y, rx, ry); 22 | } 23 | return d; 24 | } 25 | array position(T_large d) const{ 26 | assert(0 <= d && d < T_large(1) * size * size); 27 | T x = 0, y = 0; 28 | for(auto s = T(1); s < size; s <<= 1){ 29 | bool rx = (d >> 1) & 1, ry = (d ^ rx) & 1; 30 | rotate(s, x, y, rx, ry); 31 | x += s * rx, y += s * ry; 32 | d >>= 2; 33 | } 34 | return {x, y}; 35 | } 36 | }; 37 | ]]> 38 | 39 | hilbert_curve_2d --> 40 | 41 | source.c++ --> 42 | 43 | -------------------------------------------------------------------------------- /Library/Miscellaneous/logging_allocator.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | struct logging_allocator{ 5 | using value_type = T; 6 | allocator a; 7 | logging_allocator() = default; 8 | template 9 | logging_allocator(const logging_allocator&) {} 10 | T *allocate(size_t n){ 11 | cerr << "Allocating " << n << " bytes." << endl; 12 | return a.allocate(n); 13 | } 14 | void deallocate(T *ptr, size_t n) { 15 | cerr << "Deallocating " << n << " bytes." << endl; 16 | return a.deallocate(ptr, n); 17 | } 18 | }; 19 | ]]> 20 | 21 | logging_allocator --> 22 | 23 | source.c++ --> 24 | 25 | -------------------------------------------------------------------------------- /Library/Miscellaneous/mex.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | &a){ 4 | int n = (int)a.size(); 5 | static vector found; 6 | found.assign(n + 1, false); 7 | for(auto x: a) if(x <= n) found[x] = true; 8 | int res = 0; 9 | while(found[res]) ++ res; 10 | return res; 11 | } 12 | ]]> 13 | 14 | mex --> 15 | 16 | source.c++ --> 17 | 18 | -------------------------------------------------------------------------------- /Library/Miscellaneous/next_bit_permutation.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | T next_bit_permutation(T x){ 5 | T y = x | x - 1; 6 | if constexpr(sizeof(T) == 32) return y + 1 | (~y & -~y) - 1 >> (__builtin_ctz(x) + 1); 7 | else return y + 1 | (~y & -~y) - 1 >> (__builtin_ctzll(x) + 1); 8 | } 9 | ]]> 10 | 11 | next_bit_permutation --> 12 | 13 | source.c++ --> 14 | 15 | -------------------------------------------------------------------------------- /Library/Miscellaneous/pbds.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | #include 5 | using namespace __gnu_pbds; 6 | struct splitmix64_hash{ 7 | static unsigned long long _splitmix64(unsigned long long x){ 8 | x += 0x9e3779b97f4a7c15; 9 | x = (x ^ x >> 30) * 0xbf58476d1ce4e5b9; 10 | x = (x ^ x >> 27) * 0x94d049bb133111eb; 11 | return x ^ x >> 31; 12 | } 13 | size_t operator()(unsigned long long x) const{ 14 | static const unsigned long long FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); 15 | return _splitmix64(x + FIXED_RANDOM); 16 | } 17 | template 18 | size_t operator()(const vector &a) const{ 19 | static const unsigned long long FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); 20 | unsigned long long h = 0; 21 | for(auto c: a) h = _splitmix64(FIXED_RANDOM * h + c); 22 | return h; 23 | } 24 | }; 25 | template> 26 | using indexable_map = tree; 27 | template> 28 | using indexable_set = indexable_map; 29 | template 30 | using hash_map = __gnu_pbds::gp_hash_table; 31 | template 32 | using hash_set = hash_map; 33 | ]]> 34 | 35 | pbds --> 36 | 37 | source.c++ --> 38 | 39 | -------------------------------------------------------------------------------- /Library/Miscellaneous/png_parser.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | , unsigned int, unsigned int> 6 | decode(const char *file){ 7 | vector image; 8 | unsigned int width, height; 9 | if(auto error = lodepng::decode(image, width, height, file)){ 10 | cerr << "Decoder Error " << error << ": " << lodepng_error_text(error) << endl; 11 | exit(1); 12 | } 13 | return {image, width, height}; 14 | } 15 | static void encode( 16 | const vector &image, 17 | unsigned int width, 18 | unsigned int height, 19 | const char *file 20 | ){ 21 | if(auto error = lodepng::encode(file, image, width, height)){ 22 | cerr << "Encoder Error " << error << ": "<< lodepng_error_text(error) << endl; 23 | exit(2); 24 | } 25 | } 26 | }; 27 | ]]> 28 | 29 | png_parser --> 30 | 31 | source.c++ --> 32 | 33 | -------------------------------------------------------------------------------- /Library/Miscellaneous/random.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | ; 6 | using randll_t = uniform_int_distribution; 7 | using randd_t = uniform_real_distribution; 8 | // return x with probability p, y with probability 1-p 9 | template 10 | T pick(T x, T y, double p = 0.5){ 11 | assert(-0.0001 <= p && p <= 1.0001); 12 | return randd_t(0, 1)(rng) <= p ? x : y; 13 | } 14 | array gen_range(int n, bool allow_empty_range = false){ 15 | if(allow_empty_range){ 16 | int l = rng() % (n + 1), r = rng() % (n + 1); 17 | if(l > r) swap(l, r); 18 | return {l, r}; 19 | } 20 | else{ 21 | int l = rng() % n, r = rng() % n; 22 | if(l > r) swap(l, r); 23 | return {l, r + 1}; 24 | } 25 | } 26 | template 27 | vector sample_array(int n, T low, T high, bool distinct = false){ 28 | assert(low < high && (!distinct || high - low >= n)); 29 | set used; 30 | vector array(n); 31 | for(auto i = 0; i < n; ++ i){ 32 | T x = randll_t(low, high - 1)(rng); 33 | if(distinct){ 34 | if(used.count(x)){ 35 | -- i; 36 | continue; 37 | } 38 | used.insert(x); 39 | } 40 | array[i] = x; 41 | } 42 | return array; 43 | } 44 | ]]> 45 | 46 | random --> 47 | 48 | source.c++ --> 49 | 50 | -------------------------------------------------------------------------------- /Library/Miscellaneous/type_name.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | string_view type_name(){ 5 | const auto s = string_view(__PRETTY_FUNCTION__); 6 | return s.substr(39, s.size() - 89); 7 | } 8 | ]]> 9 | 10 | type_name --> 11 | 12 | source.c++ --> 13 | 14 | -------------------------------------------------------------------------------- /Library/Miscellaneous/value_compressor.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | struct value_compressor{ 5 | vector _cmpr; 6 | #if __cplusplus >= 202002L 7 | template 8 | void _collect(const Range &data){ 9 | if constexpr(is_convertible_v, T>) _cmpr.insert(_cmpr.end(), ranges::begin(data), ranges::end(data)); 10 | else for(const auto &sub: data) _collect(sub); 11 | } 12 | template 13 | void init(const Range &data){ 14 | _cmpr.clear(); 15 | _collect(data); 16 | ranges::sort(_cmpr); 17 | _cmpr.erase(unique(_cmpr.begin(), _cmpr.end()), _cmpr.end()); 18 | } 19 | #else 20 | template 21 | void _collect(const Container &data){ 22 | if constexpr(is_convertible_v) _cmpr.insert(_cmpr.end(), data.begin(), data.end()); 23 | else for(const auto &sub: data) _collect(sub); 24 | } 25 | template 26 | void init(const Container &data){ 27 | _cmpr.clear(); 28 | _collect(data); 29 | sort(_cmpr.begin(), _cmpr.end()); 30 | _cmpr.erase(unique(_cmpr.begin(), _cmpr.end()), _cmpr.end()); 31 | } 32 | #endif 33 | int operator()(const T &x) const{ 34 | return lower_bound(_cmpr.begin(), _cmpr.end(), x) - _cmpr.begin(); 35 | } 36 | int size() const{ 37 | return (int)_cmpr.size(); 38 | } 39 | }; 40 | ]]> 41 | 42 | value_compressor --> 43 | 44 | source.c++ --> 45 | 46 | -------------------------------------------------------------------------------- /Library/Miscellaneous/y_combinator.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | struct y_combinator_result{ 5 | F f; 6 | template explicit y_combinator_result(T &&f): f(forward(f)){ } 7 | template decltype(auto) operator()(Args &&...args){ return f(ref(*this), forward(args)...); } 8 | }; 9 | template 10 | decltype(auto) y_combinator(F &&f){ 11 | return y_combinator_result>(forward(f)); 12 | } 13 | ]]> 14 | 15 | y_combinator --> 16 | 17 | source.c++ --> 18 | 19 | -------------------------------------------------------------------------------- /Library/Number_Theory/Integer_Decomposition/solve_fermat_three_triangle.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 8 | array solve_fermat_three_triangle(T n){ 9 | assert(n >= 0); 10 | auto res = solve_legendre_three_square(8 * n + 3); 11 | res = {res[0] / 2, res[1] / 2, res[2] / 2}; 12 | assert(*min_element(res.begin(), res.end()) >= 0); 13 | assert(res[0] * (res[0] + 1) / 2 + res[1] * (res[1] + 1) / 2 + res[2] * (res[2] + 1) / 2 == n); 14 | return res; 15 | } 16 | ]]> 17 | 18 | solve_fermat_three_triangle --> 19 | 20 | source.c++ --> 21 | 22 | -------------------------------------------------------------------------------- /Library/Number_Theory/Modular/mod_sqrt.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 8 | optional mod_sqrt(T a){ 9 | int p = T().mod(); 10 | if(a == 0) return 0; 11 | if((a.power((p - 1) / 2)) != 1) return {}; 12 | if(p % 4 == 3) return a.power((p + 1) / 4); 13 | // a^(n+3)/8 or 2^(n+3)/8 * 2^(n-1)/4 works if p % 8 == 5 14 | int s = p - 1, r = 0, m; 15 | while(s % 2 == 0) ++ r, s /= 2; 16 | T n = 2; 17 | while(n.power((p - 1) / 2) != p - 1) ++ n; 18 | T x = a.power((s + 1) / 2), b = a.power(s), g = n.power(s); 19 | for( ; ; r = m){ 20 | T t = b; 21 | for(m = 0; m < r && t != 1; ++ m) t *= t; 22 | if(m == 0) return x; 23 | T gs = g.power(1LL << r - m - 1); 24 | g = gs * gs, x = x * gs, b = b * g; 25 | } 26 | } 27 | ]]> 28 | 29 | mod_sqrt --> 30 | 31 | source.c++ --> 32 | 33 | -------------------------------------------------------------------------------- /Library/Number_Theory/Multiplicative_Prefix_Sum/xudyh_sieve.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | struct xudyh_sieve{ 5 | int th; // threshold, ideally about (2(single query) ~ 5(lots of queries)) * MAXN^2/3 6 | F1 pf; // prefix sum of f / precalculate it up to th 7 | F2 pg; // prefix sum of g / should be easy to calculate 8 | F3 pfg; // prefix sum of dirichlet convolution of f and g / should be easy to calculate 9 | unordered_map mp; 10 | xudyh_sieve(int th, F1 pf, F2 pg, F3 pfg): th(th), pf(pf), pg(pg), pfg(pfg){ } 11 | // Calculate the preix sum of a multiplicative f up to n 12 | // O(n^2/3) applications of pf(), pg(), and pfg() 13 | T query(long long n){ 14 | if(n <= th) return pf(n); 15 | if(mp.count(n)) return mp[n]; 16 | T res = pfg(n); 17 | for(long long low = 2LL, high = 2LL; low <= n; low = high + 1){ 18 | high = n / (n / low); 19 | res -= (pg(high) - pg(low - 1)) * query(n / low); 20 | } 21 | return mp[n] = res / pg(1); 22 | } 23 | }; 24 | ]]> 25 | 26 | xudyh_sieve --> 27 | 28 | source.c++ 29 | 30 | -------------------------------------------------------------------------------- /Library/Number_Theory/barret_reduction.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > 64); 17 | unsigned int v = (unsigned int)(z - x * _m); 18 | if(_m <= v) v += _m; 19 | return v; 20 | } 21 | }; 22 | ]]> 23 | 24 | barret_reduction --> 25 | 26 | source.c++ --> 27 | 28 | -------------------------------------------------------------------------------- /Library/Number_Theory/dirichlet_convolution_formulae.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 32 | 33 | dirichlet_convolution_formulae --> 34 | 35 | source.c++ --> 36 | 37 | -------------------------------------------------------------------------------- /Library/Number_Theory/divisor_count_function_prefix_sum.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | T divisor_count_function_prefix_sum(U n){ 5 | T res = 0; 6 | int th = sqrt(n); 7 | for(auto x = 1; x <= th; ++ x) res += n / x; 8 | for(auto y = 1; th < n / y; ++ y) res += n / y - th; 9 | return res; 10 | } 11 | ]]> 12 | 13 | divisor_count_function_prefix_sum --> 14 | 15 | source.c++ --> 16 | 17 | -------------------------------------------------------------------------------- /Library/Number_Theory/extended_euclidean.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | T extended_euclidean(T a, T b, T &x, T &y){ 7 | if(a < 0) a = -a; 8 | if(b < 0) b = -b; 9 | x = 1, y = 0; 10 | for(T q, r, u = 0, v = 1; b; ){ 11 | q = a / b, r = a % b; 12 | tie(a, b, x, y, u, v) = tuple{b, r, u, v, x - u * q, y - v * q}; 13 | } 14 | return a; 15 | } 16 | ]]> 17 | 18 | extended_euclidean --> 19 | 20 | source.c++ --> 21 | 22 | -------------------------------------------------------------------------------- /Library/Number_Theory/factorize.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | vector> factorize(T x){ 5 | vector> res; 6 | for(T p = 2; p * p <= x; ++ p) if(x % p == 0){ 7 | res.push_back({p, 0}); 8 | while(x % p == 0) ++ res.back().second, x /= p; 9 | } 10 | if(x > 1) res.push_back({x, 1}); 11 | return res; 12 | } 13 | ]]> 14 | 15 | factorize 16 | 17 | source.c++ 18 | 19 | -------------------------------------------------------------------------------- /Library/Number_Theory/find_first_residue.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | ::max() if no such solutions) 5 | // O(log min(m, a)) 6 | template 7 | T find_first_residue(T m, T a, T l, T r){ 8 | l = clamp(l, 0, m - 1), r = clamp(r, 0, m - 1); 9 | if(l == 0) return 0; 10 | a %= m; 11 | T res = 0, s1 = 1, s2 = 0; 12 | while(a){ 13 | if(2 * a > m){ 14 | a = m - a, l = m - l, r = m - r; 15 | swap(l, r); 16 | res += s2, s1 -= s2, s2 *= -1; 17 | } 18 | T ff = (l + a - 1) / a; 19 | if(a * ff <= r) return res + ff * s1; 20 | res += (ff - 1) * s1, ff = (ff - 1) * a, l -= ff, r -= ff; 21 | T z = (m + a - 1) / a; 22 | s2 = s1 * z - s2; 23 | swap(s1, s2); 24 | m = z * a - m; 25 | swap(a, m); 26 | } 27 | return numeric_limits::max(); 28 | } 29 | ]]> 30 | 31 | find_first_residue --> 32 | 33 | source.c++ --> 34 | 35 | -------------------------------------------------------------------------------- /Library/Number_Theory/floor_sum.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | U floor_sum(T n, T m, T a, T b){ 8 | assert(n >= 0 && m > 0 && a >= 0; 9 | U res = 0; 10 | auto [qa, ra] = div(a, m); 11 | auto [qb, rb] = div(b, m); 12 | if(rb < 0){ 13 | rb += m; 14 | -- qb; 15 | } 16 | if(T n2 = (ra * n + rb) / m){ 17 | auto prev = floor_sum(n2, ra, m, m - rb - 1); 18 | res += U(n - 1) * n2 - prev; 19 | } 20 | res += (n & 1 ? U(n - 1 >> 1) * n : U(n >> 1) * (n - 1)) * qa + U(n) * qb; 21 | return res; 22 | } 23 | ]]> 24 | 25 | floor_sum --> 26 | 27 | source.c++ --> 28 | 29 | -------------------------------------------------------------------------------- /Library/Number_Theory/floor_sum_weighted.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 10 | array floor_sum_weighted(T n, T m, T a, T b){ 11 | assert(n >= 0 && m > 0 && a >= 0); 12 | array res{}; 13 | auto [qa, ra] = div(a, m); 14 | auto [qb, rb] = div(b, m); 15 | if(rb < 0){ 16 | rb += m; 17 | -- qb; 18 | } 19 | if(T n2 = (ra * n + rb) / m){ 20 | auto prev = floor_sum_weighted(n2, ra, m, m - rb - 1); 21 | res[0] += U(n - 1) * n2 - prev[0]; 22 | res[1] += (U(n - 1) * n * n2 - prev[0] - prev[2]) / 2; 23 | res[2] += U(n - 1) * (n2 - 1) * n2 - 2 * prev[1] + res[0]; 24 | } 25 | res[2] += U(n - 1) * n * (2 * n - 1) / 6 * qa * qa + U(n) * qb * qb + U(n - 1) * n * qa * qb + 2 * res[0] * qb + 2 * res[1] * qa; 26 | res[0] += U(n - 1) * n / 2 * qa + U(n) * qb; 27 | res[1] += U(n - 1) * n * (2 * n - 1) / 6 * qa + U(n - 1) * n / 2 * qb; 28 | return res; 29 | } 30 | ]]> 31 | 32 | floor_sum_weighted --> 33 | 34 | source.c++ --> 35 | 36 | -------------------------------------------------------------------------------- /Library/Number_Theory/for_each_divisor.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | void for_each_divisor(const vector> &fact, auto f){ 5 | T d = 1; 6 | auto solve = [&](auto self, int i)->void{ 7 | if(i == (int)fact.size()){ 8 | f(d); 9 | return; 10 | } 11 | self(self, i + 1); 12 | auto [p, t] = fact[i]; 13 | T pd = d; 14 | for(auto e = 1; e <= t; ++ e) d *= p, self(self, i + 1); 15 | d = pd; 16 | }; 17 | solve(solve, 0); 18 | } 19 | ]]> 20 | 21 | divisor 22 | 23 | source.c++ --> 24 | 25 | -------------------------------------------------------------------------------- /Library/Number_Theory/harmonic_loop.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 8 | void harmonic_loop(T n, auto f, bool in_order = false){ 9 | if(in_order) for(T l = 1, r, q; l <= n; l = r + 1){ 10 | q = n / l; 11 | r = n / q; 12 | f(l, r, q); 13 | } 14 | else for(T x = 1, y, py; x * x <= n; ++ x){ 15 | y = n / x; 16 | f(x, x, y); 17 | if(x >= 2) f(y + 1, py, x - 1); 18 | if(x != y && x * x < n && (x + 1) * (x + 1) > n) f(x + 1, y, x); 19 | py = y; 20 | } 21 | } 22 | ]]> 23 | 24 | harmonic_loop --> 25 | 26 | source.c++ --> 27 | 28 | -------------------------------------------------------------------------------- /Library/Number_Theory/inverse_linear_congruential_generator.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | = 0 with s_n = obj where s_0 = s and s_{i+1} = s_i * a + b 4 | // O(sqrt(mod) + log(max(s, a, b))) 5 | // T must be of modular type 6 | // Requires modular 7 | template 8 | auto inverse_linear_congruential_generator(T s, T a, T b, T obj){ 9 | using U = decay_t; 10 | if(s == obj) return optional{0}; 11 | if(a == 1){ 12 | if(auto inverse_ptr = b.inverse()) return optional{((obj - s) * *inverse_ptr).data()}; 13 | else return optional{}; 14 | } 15 | T c = b / (a - 1); 16 | if(s + c == 0) return optional{}; 17 | if(auto resptr = ((obj + c) / (s + c)).log(a)) return resptr; 18 | return optional{}; 19 | } 20 | ]]> 21 | 22 | inverse_linear_congruential_generator --> 23 | 24 | source.c++ --> 25 | 26 | -------------------------------------------------------------------------------- /Library/Number_Theory/jacobi_symbol.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | T jacobi_symbol(T a, T n){ 5 | assert(n > 0 && ~n & 1); 6 | a = a % n; 7 | T t = 1, r; 8 | for(; a; a %= n){ 9 | while(a % 2 == 0){ 10 | a /= 2; 11 | r = n % 8; 12 | if(r == 3 || r == 5) t = -t; 13 | } 14 | r = n, n = a, a = r; 15 | if(a % 4 == 3 && n % 4 == 3) t = -t; 16 | } 17 | return n == 1 ? t : 0; 18 | } 19 | ]]> 20 | 21 | jacobi_symbol --> 22 | 23 | source.c++ --> 24 | 25 | -------------------------------------------------------------------------------- /Library/Numeric/binary_geometric_sum.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | T binary_geometric_sum(T x, U b, V e){ 7 | assert(e >= 0); 8 | T res{}; // This should be the additive identity 9 | for(; e; e >>= 1){ 10 | if(e & 1){ 11 | res = x + res; 12 | x *= b; 13 | } 14 | x += x * b; 15 | b *= b; 16 | } 17 | return res; 18 | } 19 | ]]> 20 | 21 | binary_geometric_sum --> 22 | 23 | source.c++ --> 24 | 25 | -------------------------------------------------------------------------------- /Library/Numeric/binary_geometric_sum_general.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 11 | T binary_geometric_sum_general(T x, U b, V e, T T_id, auto add, auto apply, auto merge){ 12 | assert(e >= 0); 13 | T res = T_id; 14 | for(; e; e >>= 1){ 15 | if(e & 1){ 16 | res = add(x, res); 17 | x = apply(b, x); 18 | } 19 | x = add(x, apply(b, x)); 20 | b = merge(b, b); 21 | } 22 | return res; 23 | } 24 | ]]> 25 | 26 | binary_geometric_sum_general --> 27 | 28 | source.c++ --> 29 | 30 | -------------------------------------------------------------------------------- /Library/Numeric/binary_power.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | T binary_power(T b, U e){ 7 | T res = 1; 8 | for(; e; e >>= 1, b *= b) if(e & 1) res *= b; 9 | return res; 10 | } 11 | ]]> 12 | 13 | binary_power --> 14 | 15 | source.c++ --> 16 | 17 | -------------------------------------------------------------------------------- /Library/Numeric/binary_power_general.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > 6 | T binary_power_general(T b, U e, F multiply = multiplies<>(), T one = 1){ 7 | T res = one; 8 | for(; e; e >>= 1, b = multiply(b, b)) if(e & 1) res = multiply(res, b); 9 | return res; 10 | } 11 | ]]> 12 | 13 | binary_power_general --> 14 | 15 | source.c++ --> 16 | 17 | -------------------------------------------------------------------------------- /Library/Numeric/continuous_binary_search.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | double continuous_binary_search(double low, double high, auto pred){ 8 | assert(low <= high); 9 | for(auto rep = 0; rep < iter; ++ rep){ 10 | double mid = (low + high) / 2; 11 | pred(mid) ? low = mid : high = mid; 12 | } 13 | return (low + high) / 2; 14 | } 15 | ]]> 16 | 17 | continuous_binary_search --> 18 | 19 | source.c++ --> 20 | 21 | -------------------------------------------------------------------------------- /Library/Numeric/counting_iterator.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | struct counting_iterator{ 5 | T value = 0; 6 | using iterator_category = random_access_iterator_tag; 7 | using value_type = T; 8 | using difference_type = T; 9 | using pointer = T *; 10 | using reference = T &; 11 | counting_iterator(){ } 12 | counting_iterator(const T &value): value(value){ } 13 | counting_iterator(const counting_iterator &it): value(it.value){ } 14 | T &operator*(){ return value; } 15 | T operator-(const counting_iterator &it) const{ return value - it.value; } 16 | counting_iterator &operator++(){ return ++ value, *this; } 17 | counting_iterator &operator--(){ return -- value, *this; } 18 | counting_iterator &operator+=(const T &x){ return value += x, *this; } 19 | bool operator==(const counting_iterator &otr) const{ return value == otr.value; } 20 | }; 21 | using iterint = counting_iterator; 22 | using iterll = counting_iterator; 23 | using iterlll = counting_iterator<__int128_t>; 24 | ]]> 25 | 26 | counting_iterator --> 27 | 28 | source.c++ --> 29 | 30 | -------------------------------------------------------------------------------- /Library/Numeric/discrete_golden_section_search.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | f(i+1) if i> 11 | T discrete_golden_section_search(T low, T high, auto f, Compare cmp = less<>()){ 12 | assert(low < high); 13 | if(high - low >= 10){ 14 | double phi = (sqrt(5) - 1) / 2; 15 | T mid1 = high - (high - low) * phi, mid2 = low + (high - low) * phi; 16 | auto val1 = f(mid1), val2 = f(mid2); 17 | while(high - low >= 10){ 18 | if(cmp(val1, val2)){ 19 | high = mid2, mid2 = mid1, val2 = val1; 20 | mid1 = high - (high - low) * phi, val1 = f(mid1); 21 | } 22 | else{ 23 | low = mid1, mid1 = mid2, val1 = val2; 24 | mid2 = low + (high - low) * phi, val2 = f(mid2); 25 | } 26 | } 27 | } 28 | T res = low; 29 | auto val = f(res); 30 | for(auto x = low + 1; x < high; ++ x) if(auto xval = f(x); cmp(xval, val)) res = x, val = xval; 31 | return res; 32 | } 33 | ]]> 34 | 35 | discrete_golden_section_search --> 36 | 37 | source.c++ --> 38 | 39 | -------------------------------------------------------------------------------- /Library/Numeric/discrete_ternary_search.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | f(i+1) if i> 10 | T discrete_ternary_search(T low, T high, auto f, Compare cmp = less<>()){ 11 | assert(low < high); 12 | while(high - low >= 3){ 13 | T mid = low + (high - low >> 1); 14 | cmp(f(mid), f(mid + 1)) ? high = mid + 1 : low = mid; 15 | } 16 | T res = low; 17 | auto val = f(res); 18 | for(auto x = low + 1; x < high; ++ x) if(auto xval = f(x); cmp(xval, val)) res = x, val = xval; 19 | return res; 20 | } 21 | ]]> 22 | 23 | discrete_ternary_search --> 24 | 25 | source.c++ --> 26 | 27 | -------------------------------------------------------------------------------- /Library/Numeric/find_prefix_xor_order.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 8 | int find_prefix_xor_order(vector a, const vector &b){ 9 | assert((int)a.size() == (int)b.size()); 10 | int n = (int)a.size(), s = 0; 11 | while(s < n && !a[s]){ 12 | if(b[s]) return -1; 13 | ++ s; 14 | } 15 | if(s == n) return 0; 16 | if(a[s] != b[s]) return -1; 17 | int res = 0; 18 | for(auto bit = 0; s + (1 << bit) <= n; ++ bit){ 19 | if(equal(a.begin() + s + (1 << bit), a.begin() + min(s + (1 << bit + 1), n), b.begin() + s + (1 << bit), b.begin() + min(s + (1 << bit + 1), n))) continue; 20 | res |= 1 << bit; 21 | for(auto i = s + (1 << bit); i < n; ++ i) a[i] ^= a[i - (1 << bit)]; 22 | if(!equal(a.begin() + s + (1 << bit), a.begin() + min(s + (1 << bit + 1), n), b.begin() + s + (1 << bit), b.begin() + min(s + (1 << bit + 1), n))) return -1; 23 | } 24 | return res; 25 | } 26 | ]]> 27 | 28 | find_prefix_xor_order --> 29 | 30 | source.c++ --> 31 | 32 | -------------------------------------------------------------------------------- /Library/Numeric/golden_section_search.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > 10 | double golden_section_search(double low, double high, int repeat, auto f, Compare cmp = less<>()){ 11 | assert(low < high); 12 | double phi = (sqrt(5) - 1) / 2, mid1 = high - (high - low) * phi, mid2 = low + (high - low) * phi; 13 | auto val1 = f(mid1), val2 = f(mid2); 14 | while(repeat --){ 15 | if(cmp(val1, val2)){ 16 | high = mid2, mid2 = mid1, val2 = val1; 17 | mid1 = high - (high - low) * phi, val1 = f(mid1); 18 | } 19 | else{ 20 | low = mid1, mid1 = mid2, val1 = val2; 21 | mid2 = low + (high - low) * phi, val2 = f(mid2); 22 | } 23 | } 24 | return (low + high) / 2; 25 | } 26 | ]]> 27 | 28 | golden_section_search --> 29 | 30 | source.c++ --> 31 | 32 | -------------------------------------------------------------------------------- /Library/Numeric/parallel_binary_search.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | parallel_binary_search(int n, int low, int high, auto init, auto advance, auto pred){ 12 | assert(low <= high); 13 | vector l(n, low), r(n, high); 14 | vector> update(high - low); 15 | init(); 16 | for(auto i = 0; i < n; ++ i) if(!pred(i)) r[i] = low; 17 | while(true){ 18 | bool done = true; 19 | for(auto i = 0; i < n; ++ i) if(r[i] - l[i] >= 2){ 20 | done = false; 21 | update[l[i] + (r[i] - l[i] >> 1) - low].push_back(i); 22 | } 23 | if(done) break; 24 | for(auto s = low; s < high; ++ s){ 25 | for(auto i: update[s - low]) (pred(i) ? l : r)[i] = s; 26 | update[s - low].clear(); 27 | if(s + 1 < high) advance(s); 28 | } 29 | init(); 30 | } 31 | return r; 32 | } 33 | ]]> 34 | 35 | parallel_binary_search --> 36 | 37 | source.c++ --> 38 | 39 | -------------------------------------------------------------------------------- /Library/Numeric/solve_cubic_equation.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 10 | optional>> solve_cubic_equation(T a, T b, T c, T d, const long double &eps = 1e-10){ 11 | using ld = long double; 12 | using cld = complex; 13 | if(abs(a) > eps){ 14 | cld D0 = b * b - 3.0l * a * c; 15 | cld D1 = 2.0l * b * b * b - 9.0l * a * b * c + 27.0l * a * a * d; 16 | cld C = pow((D1 + sqrt(D1 * D1 - 4.0l * D0 * D0 * D0)) / 2.0l, 1.0l / 3.0l); 17 | vector res; 18 | for(auto zeta: {cld(1.0l), -0.5l + sqrtl(3) * 0.5il, -0.5l - sqrtl(3.0l) * 0.5il}){ 19 | res.push_back(-1 / (3.0l * a) * (b + (abs(C) > eps ? zeta * C + D0 / (zeta * C) : 0.0l))); 20 | } 21 | return res; 22 | } 23 | else if(abs(b) > eps){ 24 | cld D = c * c - 4.0l * b * d; 25 | return {{(-c + sqrt(D)) / (2.0l * b), (-c - sqrt(D)) / (2.0l * b)}}; 26 | } 27 | else if(abs(c) > eps) return {{-d / c}}; 28 | else if(abs(d) > eps) return vector>{}; 29 | else return {}; 30 | } 31 | ]]> 32 | 33 | solve_cubic_equation --> 34 | 35 | source.c++ --> 36 | 37 | -------------------------------------------------------------------------------- /Library/Power_Series/Bell_Number/bell_number.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 11 | vector bernoulli_number(int n){ 12 | assert(n >= 0); 13 | power_series_base B(n + 1); 14 | T fact = 1; 15 | for(auto x = 2; x <= n + 1; ++ x) fact *= x; 16 | B[n] = fact = 1 / fact; 17 | for(auto x = n - 1; x >= 0; -- x) B[x] = fact *= x + 2; 18 | B.inplace_inverse(n + 1); 19 | for(auto x = 2; x <= n; ++ x) B[x] *= fact *= x; 20 | return B; 21 | } 22 | ]]> 23 | 24 | bell_number --> 25 | 26 | source.c++ --> 27 | 28 | -------------------------------------------------------------------------------- /Library/Power_Series/Convolutions/convolve_subset.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | vector convolve_subset(const vector &p, const vector &q){ 7 | int n = (int)p.size(); 8 | assert((int)q.size() == n && __builtin_popcount(n) == 1); 9 | int w = __lg(n); 10 | assert(w <= SZ); 11 | vector> x(n), y(n); 12 | for(auto i = 0; i < n - 1; ++ i) x[i][__builtin_popcount(i)] = p[i]; 13 | for(auto k = 0; k < w; ++ k) for(auto i = 0; i < n; ++ i) if(~i >> k & 1) for(auto j = 0; j < w; ++ j) x[i | 1 << k][j] += x[i][j]; 14 | for(auto i = 0; i < n - 1; ++ i) y[i][__builtin_popcount(i)] = q[i]; 15 | for(auto k = 0; k < w; ++ k) for(auto i = 0; i < n; ++ i) if(~i >> k & 1) for(auto j = 0; j < w; ++ j) y[i | 1 << k][j] += y[i][j]; 16 | for(auto i = 0; i < n; ++ i) for(auto j = w - 1; j >= 0; -- j){ 17 | for(auto k = 1; k < w - j; ++ k) x[i][j + k] += x[i][j] * y[i][k]; 18 | x[i][j] *= y[i][0]; 19 | } 20 | for(auto k = 0; k < w; ++ k) for(auto i = 0; i < n; ++ i) if(~i >> k & 1) for(auto j = 0; j < w; ++ j) x[i | 1 << k][j] -= x[i][j]; 21 | vector res(n); 22 | for(auto i = 0; i < n - 1; ++ i) res[i] = x[i][__builtin_popcount(i)]; 23 | for(auto i = 0; i < n; ++ i) res[n - 1] += p[i] * q[n - 1 - i]; 24 | return res; 25 | } 26 | ]]> 27 | 28 | convolve_subset --> 29 | 30 | source.c++ --> 31 | 32 | -------------------------------------------------------------------------------- /Library/Power_Series/Power_Sum/bernoulli_number.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 11 | vector bernoulli_number(int n){ 12 | assert(n >= 0); 13 | power_series_base B(n + 1); 14 | T fact = 1; 15 | for(auto x = 2; x <= n + 1; ++ x) fact *= x; 16 | B[n] = fact = 1 / fact; 17 | for(auto x = n - 1; x >= 0; -- x) B[x] = fact *= x + 2; 18 | B.inplace_inverse(n + 1); 19 | for(auto x = 2; x <= n; ++ x) B[x] *= fact *= x; 20 | return B; 21 | } 22 | ]]> 23 | 24 | bernoulli_number --> 25 | 26 | source.c++ --> 27 | 28 | -------------------------------------------------------------------------------- /Library/Power_Series/Power_Sum/power_sum.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | T power_sum(T base, int d){ 7 | assert(d >= 0); 8 | vector value(d + 2), fact(d + 2, 1), pref(d + 3, 1), suff(d + 3, 1); 9 | for(auto x = 0; x <= d; ++ x){ 10 | T temp = x; 11 | value[x + 1] = 1; 12 | for(auto e = d; e; e >>= 1, temp *= temp) if(e & 1) value[x + 1] *= temp; 13 | value[x + 1] += value[x]; 14 | pref[x + 1] = pref[x] * (base - x) / (x + 1); 15 | } 16 | for(auto x = d + 1; x >= 1; -- x) suff[x] = suff[x + 1] * (base - x) / (d + 2 - x); 17 | T res = 0; 18 | for(auto x = 0; x <= d + 1; ++ x) res += value[x] * pref[x] * suff[x + 1] * (d + 1 - x & 1 ? -1 : 1); 19 | return res; 20 | } 21 | ]]> 22 | 23 | power_sum --> 24 | 25 | source.c++ --> 26 | 27 | -------------------------------------------------------------------------------- /Library/Power_Series/Power_Sum/power_sum_prefix_evaluation.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 8 | vector power_sum_prefix_evaluation(long long len, int n){ 9 | assert(n >= 0); 10 | if(!n) return {}; 11 | if(!len) return vector(n, T()); 12 | auto res = ((1 - power_series_base::EGF(n + 2, len)).drop(1) * (1 - power_series_base::EGF(n + 2)).drop(1).inverse(n + 1)).EGF_to_seq(); 13 | res.resize(n + 1); 14 | return res; 15 | } 16 | ]]> 17 | 18 | power_sum_prefix_evaluation --> 19 | 20 | source.c++ --> 21 | 22 | -------------------------------------------------------------------------------- /Library/Power_Series/Set_Power_Series/exponential_set_power_series.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | vector exponential_set_power_series(const vector &p){ 8 | int n = (int)p.size(); 9 | assert(__builtin_popcount(n) == 1 && p[0] == 0); 10 | int w = __lg(n); 11 | vector res{1}; 12 | for(auto bit = 0; bit < w; ++ bit){ 13 | auto shift = convolve_subset(res, vector(p.begin() + (1 << bit), p.begin() + (1 << bit + 1))); 14 | res.insert(res.end(), shift.begin(), shift.end()); 15 | } 16 | return res; 17 | } 18 | ]]> 19 | 20 | exponential_set_power_series --> 21 | 22 | source.c++ --> 23 | 24 | -------------------------------------------------------------------------------- /Library/Power_Series/Set_Power_Series/logarithm_set_power_series.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | vector logarithm_set_power_series(const vector &p){ 8 | int n = (int)p.size(); 9 | assert(__builtin_popcount(n) == 1 && p[0] == 1); 10 | int w = __lg(n); 11 | vector> res(w + 1, {0}); 12 | T fact = 1; 13 | for(auto bit = 1; bit <= w; ++ bit) res[bit][0] = fact, fact *= -bit; 14 | for(auto bit = 0; bit < w; ++ bit){ 15 | for(auto i = 0; i < w - bit; ++ i){ 16 | auto shift = convolve_subset(res[i + 1], vector(p.begin() + (1 << bit), p.begin() + (1 << bit + 1))); 17 | res[i].insert(res[i].end(), shift.begin(), shift.end()); 18 | } 19 | res.pop_back(); 20 | } 21 | return res[0]; 22 | } 23 | ]]> 24 | 25 | logarithm_set_power_series --> 26 | 27 | source.c++ --> 28 | 29 | -------------------------------------------------------------------------------- /Library/Power_Series/chebyshev_eval.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | T chebyshev_eval(U n, T x){ 6 | if(n < 0) n = -n; 7 | auto recurse = [&](auto self, U n, T x)->array{ 8 | if(n == 0) return {1, x}; 9 | auto [a, b] = self(self, n >> 1, x); 10 | auto c = 2 * a * a - 1, d = 2 * a * b - x; 11 | if(~n & 1) return {c, d}; 12 | auto e = 2 * x * d - c; 13 | return {d, e}; 14 | }; 15 | return recurse(recurse, n, x)[0]; 16 | } 17 | ]]> 18 | 19 | chebyshev_eval --> 20 | 21 | source.c++ --> 22 | 23 | -------------------------------------------------------------------------------- /Library/Power_Series/interpolate_range_naive.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | vector interpolate_range_naive(U base, const vector &y){ 7 | int n = (int)y.size(); 8 | assert(n >= 1); 9 | vector invfact(n, 1); 10 | for(auto x = 2; x < n; ++ x) invfact[n - 1] *= x; 11 | invfact[n - 1] = 1 / invfact[n - 1]; 12 | for(auto x = n - 2; x >= 0; -- x) invfact[x] = invfact[x + 1] * (x + 1); 13 | vector res(n), p(n + 1); 14 | p[0] = 1; 15 | for(auto i = 0; i < n; ++ i){ 16 | T x = base + i; 17 | for(auto j = i + 1; j >= 1; -- j) p[j] = p[j - 1] - x * p[j]; 18 | p[0] *= -x; 19 | } 20 | for(auto i = 0; i < n; ++ i){ 21 | T x = base + i, coef = y[i] * invfact[i] * invfact[n - 1 - i] * (n - 1 - i & 1 ? -1 : 1); 22 | for(auto j = n - 1; j >= 1; -- j) p[j] += x * p[j + 1]; 23 | p[0] = 0; 24 | rotate(p.begin(), p.begin() + 1, p.end()); 25 | for(auto j = 0; j < n; ++ j) res[j] += coef * p[j]; 26 | for(auto j = n; j >= 1; -- j) p[j] = p[j - 1] - x * p[j]; 27 | p[0] *= -x; 28 | } 29 | return res; 30 | } 31 | ]]> 32 | 33 | interpolate_range_naive --> 34 | 35 | source.c++ --> 36 | 37 | -------------------------------------------------------------------------------- /Library/Power_Series/power_series_composition.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Library/Power_Series/sequential_polynomial.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | vector sequential_polynomial(int n, T a){ 8 | assert(n >= 0); 9 | if(n == 0) return {1}; 10 | if(n == 1) return {-a, 1}; 11 | vector res{1}, base{-a, 1}; 12 | for(auto bit = 0, lg = __lg(n); bit <= lg; ++ bit){ 13 | if(n & 1 << bit) res = FFT::convolve(base, taylor_shift(res, 1 << bit)); 14 | base = FFT::convolve(base, taylor_shift(base, 1 << bit)); 15 | } 16 | return res; 17 | } 18 | ]]> 19 | 20 | sequential_polynomial --> 21 | 22 | source.c++ --> 23 | 24 | -------------------------------------------------------------------------------- /Library/Power_Series/taylor_shift.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | vector taylor_shift(const vector &p, T d){ 8 | if((int)p.size() <= 1) return p; 9 | int n = (int)p.size(); 10 | vector fact(n, 1), invfact(n, 1); 11 | for(auto i = 2; i < n; ++ i) fact[i] = fact[i - 1] * i; 12 | invfact[n - 1] = 1 / fact[n - 1]; 13 | for(auto i = n - 2; i >= 2; -- i) invfact[i] = invfact[i + 1] * (i + 1); 14 | vector f = p, g(n); 15 | T pow = 1; 16 | for(auto i = 0; i < n; ++ i){ 17 | f[i] *= fact[i]; 18 | g[i] = pow * invfact[i]; 19 | pow *= -d; 20 | } 21 | reverse(g.begin(), g.end()); 22 | f = FFT::convolve(f, g); 23 | f.erase(f.begin(), f.begin() + n - 1); 24 | for(auto i = 0; i < n; ++ i) f[i] *= invfact[i]; 25 | return f; 26 | } 27 | ]]> 28 | 29 | taylor_shift --> 30 | 31 | source.c++ --> 32 | 33 | -------------------------------------------------------------------------------- /Library/Power_Series/touchard_polynomial.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | vector touchard_polynomial(int n){ 7 | vector fact(n + 1, 1), invfact(n + 1, 1), p(n + 1), q(n + 1); 8 | for(auto i = 2; i <= n; ++ i) fact[i] = fact[i - 1] * i; 9 | invfact[n] = 1 / fact[n]; 10 | for(auto i = n - 1; i >= 2; -- i) invfact[i] = invfact[i + 1] * (i + 1); 11 | for(auto i = 0; i <= n; ++ i){ 12 | p[i] = invfact[i] * (i & 1 ? -1 : 1); 13 | q[i] = invfact[i] * T(i).power(n); 14 | } 15 | (p = FFT::convolve(p, q)).resize(n + 1); 16 | return p; 17 | } 18 | ]]> 19 | 20 | touchard_polynomial --> 21 | 22 | source.c++ --> 23 | 24 | -------------------------------------------------------------------------------- /Library/Random_Generators/generate_chordal_graph.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > generate_chordal_graph(auto &&rng, int n){ 4 | vector> adj(n); 5 | for(auto [u, v]: generate_tree(rng, n)){ 6 | adj[u].push_back(v); 7 | adj[v].push_back(u); 8 | } 9 | int it = 0; 10 | vector pos(n), end(n); 11 | auto dfs = [&](auto self, int u, int p)->void{ 12 | pos[u] = it ++; 13 | for(auto v: adj[u]) if(v != p) self(self, v, u); 14 | end[u] = it; 15 | }; 16 | dfs(dfs, 0, -1); 17 | vector> insert(n), erase(n + 1); 18 | for(auto i = 0; i < n; ++ i){ 19 | int u = rng() % n; 20 | insert[pos[u]].push_back(i); 21 | erase[end[u]].push_back(i); 22 | } 23 | set state; 24 | vector> res; 25 | for(auto t = 0; t < n; ++ t){ 26 | for(auto u: erase[t]) state.erase(u); 27 | for(auto u: insert[t]){ 28 | for(auto v: state) res.push_back({u, v}); 29 | state.insert(u); 30 | } 31 | } 32 | return res; 33 | } 34 | ]]> 35 | 36 | generate_chordal_graph --> 37 | 38 | source.c++ --> 39 | 40 | -------------------------------------------------------------------------------- /Library/Random_Generators/generate_colinear_points.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > generate_colinear_points(auto &&rng, int n, int low, int high){ 5 | vector> a(n); 6 | while(true){ 7 | for(auto &[x, y]: a) x = randint(low, high + 1)(rng), y = randint(low, high + 1)(rng); 8 | for(auto i = 0; i < n; ++ i) for(auto j = i + 1; j < n; ++ j)for(auto k = j + 1; k < n; ++ k) if(doubled_signed_area(a[i], a[j], a[k]) == 0) goto NEXT; 9 | break; 10 | NEXT:; 11 | } 12 | return a; 13 | } 14 | ]]> 15 | 16 | generate_colinear_points --> 17 | 18 | source.c++ --> 19 | 20 | -------------------------------------------------------------------------------- /Library/Random_Generators/generate_edge_cactus.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > generate_edge_cactus(auto &&rng, int n, double cycle_extension_prob = 0.8){ 5 | uniform_real_distribution genp(0, 1); 6 | vector> adj(n); 7 | vector> res; 8 | for(auto [u, v]: generate_tree(rng, n)){ 9 | res.push_back({u, v}); 10 | adj[u].push_back(v), adj[v].push_back(u); 11 | } 12 | vector order, pv(n, -1), depth(n); 13 | auto dfs = [&](auto self, int u, int p)->void{ 14 | order.push_back(u); 15 | pv[u] = p; 16 | for(auto v: adj[u]) if(v != p){ 17 | depth[v] = depth[u] + 1; 18 | self(self, v, u); 19 | } 20 | }; 21 | dfs(dfs, 0, -1); 22 | vector covered(n); 23 | for(auto i = n - 1; i >= 0; -- i){ 24 | int u = order[i]; 25 | if(depth[u] <= 1 || covered[u] || covered[pv[u]]){ 26 | continue; 27 | } 28 | if(genp(rng) <= cycle_extension_prob){ 29 | covered[u] = covered[pv[u]] = true; 30 | int v = pv[pv[u]]; 31 | while(v && !covered[v] && genp(rng) <= cycle_extension_prob){ 32 | covered[v] = true; 33 | v = pv[v]; 34 | } 35 | res.push_back({u, v}); 36 | } 37 | } 38 | return res; 39 | } 40 | ]]> 41 | 42 | generate_edge_cactus --> 43 | 44 | source.c++ --> 45 | 46 | -------------------------------------------------------------------------------- /Library/Random_Generators/generate_graph.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > generate_graph(auto &&rng, int n, int m){ 4 | vector> res(m); 5 | for(auto &[u, v]: res) u = rng() % n, v = rng() % n; 6 | return res; 7 | } 8 | ]]> 9 | 10 | hello --> 11 | 12 | source.c++ --> 13 | 14 | -------------------------------------------------------------------------------- /Library/Random_Generators/generate_planar_graph.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | >, vector> generate_planar_graph(auto &&rng, int n, int m_max, int max_c = 1000000000){ 5 | assert(0 <= n); 6 | vector embedding(n); 7 | for(auto u = 0; u < n; ++ u){ 8 | embedding[u].x = rng() % (max_c + 1); 9 | embedding[u].y = rng() % (max_c + 1); 10 | } 11 | vector> edge; 12 | for(auto rep = m_max; n && rep; -- rep){ 13 | int u = rng() % (n - 1), v = rng() % (n - 1 - u) + u + 1; 14 | linell L(embedding[u], embedding[v]); 15 | bool fail = false; 16 | for(auto [w, x]: edge){ 17 | linell M(embedding[w], embedding[x]); 18 | if(intersect_closed_segments(L, M)){ 19 | fail = true; 20 | break; 21 | } 22 | } 23 | if(!fail) edge.push_back({u, v}); 24 | } 25 | return {edge, embedding}; 26 | } 27 | ]]> 28 | 29 | generate_planar_graph --> 30 | 31 | source.c++ --> 32 | 33 | -------------------------------------------------------------------------------- /Library/Random_Generators/generate_simple_graph.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > generate_simple_graph(auto &&rng, int n, int m){ 4 | assert(1 <= n && 0 <= m && m <= 1LL * n * (n - 1) / 2); 5 | vector> res(m); 6 | set> s; 7 | for(auto &[u, v]: res){ 8 | do{ 9 | u = rng() % n, v = rng() % n; 10 | }while(u == v || s.count({u, v}) || s.count({v, u})); 11 | s.insert({u, v}), s.insert({v, u}); 12 | } 13 | return res; 14 | } 15 | ]]> 16 | 17 | generate_simple_graph --> 18 | 19 | source.c++ --> 20 | 21 | -------------------------------------------------------------------------------- /Library/Random_Generators/generate_simply_connected_bipartite_graph.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > generate_simply_connected_bipartite_graph(auto &&rng, int n, int trial){ 5 | assert(1 <= n && n - 1 <= trial); 6 | if(n == 1) return {}; 7 | auto res = generate_tree(rng, n); 8 | set> s; 9 | vector> adj(n); 10 | for(auto [u, v]: res) adj[u].push_back(v), adj[v].push_back(u), s.insert({u, v}), s.insert({v, u}); 11 | vector depth(n); 12 | auto dfs = [&](auto self, int u, int p)->void{ 13 | for(auto v: adj[u]) if(v != p) depth[v] = depth[u] + 1, self(self, v, u); 14 | }; 15 | dfs(dfs, 0, -1); 16 | vector left, right; 17 | for(auto u = 0; u < n; ++ u){ 18 | if(~depth[u] & 1) left.push_back(u); 19 | else right.push_back(u); 20 | } 21 | for(auto i = n - 1; i < trial; ++ i){ 22 | int u = left[rng() % (int)left.size()], v = right[rng() % (int)right.size()]; 23 | if(!s.count({u, v})){ 24 | s.insert({u, v}), s.insert({v, u}); 25 | res.push_back({u, v}); 26 | } 27 | } 28 | return res; 29 | } 30 | ]]> 31 | 32 | generate_simply_connected_bipartite_graph --> 33 | 34 | source.c++ --> 35 | 36 | -------------------------------------------------------------------------------- /Library/Random_Generators/generate_simply_connected_graph.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > generate_simply_connected_graph(auto &&rng, int n, int m){ 5 | assert(n - 1 <= m && m <= 1LL * n * (n - 1) / 2); 6 | auto res = generate_tree(rng, n); 7 | set> s; 8 | for(auto [u, v]: res) s.insert({u, v}), s.insert({v, u}); 9 | for(auto rep = n - 1; rep < m; ++ rep){ 10 | int u, v; 11 | do{ 12 | u = rng() % n, v = rng() % n; 13 | }while(u == v || s.count({u, v})); 14 | s.insert({u, v}), s.insert({v, u}); 15 | res.push_back({u, v}); 16 | } 17 | return res; 18 | } 19 | ]]> 20 | 21 | generate_simply_connected_graph --> 22 | 23 | source.c++ --> 24 | 25 | -------------------------------------------------------------------------------- /Library/Random_Generators/generate_tree.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | > generate_tree(auto &&rng, int n, optional> input_deg = {}){ 4 | if(input_deg){ 5 | assert((int)input_deg->size() == n); 6 | assert(accumulate(input_deg->begin(), input_deg->end(), 0) == 2 * n - 2); 7 | for(auto d: *input_deg) assert(1 <= d); 8 | } 9 | vector> res; 10 | if(n <= 3 || !input_deg && rng() & 1) for(auto u = 1; u < n; ++ u) res.push_back({int(rng() % u), u}); 11 | else{ 12 | vector prufer(n - 2), deg(n, 1); 13 | if(input_deg){ 14 | deg = *input_deg; 15 | prufer.clear(); 16 | for(auto u = 0; u < n; ++ u) for(auto i = 0; i < deg[u] - 1; ++ i) prufer.push_back(u); 17 | } 18 | else for(auto &u: prufer) ++ deg[u = rng() % n]; 19 | int leaf = find(deg.begin(), deg.end(), 1) - deg.begin(), u = leaf; 20 | for(auto v: prufer){ 21 | res.push_back({min(leaf, v), max(leaf, v)}); 22 | if(-- deg[v] == 1 && v < u) leaf = v; 23 | else{ 24 | u = find(deg.begin() + u + 1, deg.end(), 1) - deg.begin(); 25 | leaf = u; 26 | } 27 | } 28 | res.push_back({leaf, n - 1}); 29 | } 30 | vector label(n); 31 | iota(label.begin(), label.end(), 0); 32 | shuffle(label.begin(), label.end(), rng); 33 | for(auto &[u, v]: res){ 34 | u = label[u], v = label[v]; 35 | if(rng() & 1) swap(u, v); 36 | } 37 | shuffle(res.begin(), res.end(), rng); 38 | return res; 39 | } 40 | ]]> 41 | 42 | generate_tree --> 43 | 44 | source.c++ --> 45 | 46 | -------------------------------------------------------------------------------- /Library/String/Autocorrelation/autocorrelation_free_variable_count.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | int autocorrelation_free_variable_count(int n, const bitset &ac){ 7 | assert(0 <= n && n <= SZ); 8 | if(n == 0) return 0; 9 | int res = 0; 10 | for(auto l = 0; ; ){ 11 | int i = min(n, ac._Find_next(l)); 12 | if(i == n){ 13 | res += n - l; 14 | break; 15 | } 16 | if(i == l + 1){ 17 | ++ res; 18 | break; 19 | } 20 | if(i - l <= n - l >> 1) l = n - (i - l) - (n - l) % (i - l); 21 | else res += 2 * (i - l) - (n - l), l = i; 22 | } 23 | return res; 24 | } 25 | ]]> 26 | 27 | autocorrelation_free_variable_count --> 28 | 29 | source.c++ --> 30 | 31 | -------------------------------------------------------------------------------- /Library/String/Autocorrelation/autocorrelation_membership_test.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | bool autocorrelation_membership_test(int n, const bitset &ac){ 7 | assert(0 <= n && n <= SZ); 8 | if(n == 0) return true; 9 | for(auto l = 0; l < n; ){ 10 | if(!ac[l]) return false; 11 | int len = n - l, p = min(n, ac._Find_next(l)) - l; 12 | if(p <= len / 2){ 13 | int r = len % p, q = p + r; 14 | for(auto j = 1; j <= len - q; ++ j) if(ac[l + j] != (j % p == 0)) return false; 15 | if(r > 0 && ac[l + len - q + p] != 1) return false; 16 | if(int pw = min(n, ac._Find_next(l + len - q)) - (l + len - q); pw < p) if(pw + p <= q + gcd(pw, p)) return false; 17 | l += len - q; 18 | } 19 | else{ 20 | for(auto j = 1; j < p; ++ j) if(ac[l + j]) return false; 21 | if(p == len) return true; 22 | l += p; 23 | } 24 | } 25 | assert(false); 26 | } 27 | ]]> 28 | 29 | autocorrelation_membership_test --> 30 | 31 | source.c++ --> 32 | 33 | -------------------------------------------------------------------------------- /Library/String/Autocorrelation/string_to_autocorrelation.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | bitset string_to_autocorrelation(const vector &s){ 7 | int n = (int)s.size(); 8 | assert(0 <= n && n <= SZ); 9 | if(s.empty()) return {}; 10 | vector pi(n); 11 | for(auto i = 1; i < n; ++ i){ 12 | int len = pi[i - 1]; 13 | while(len && s[i] != s[len]) len = pi[len - 1]; 14 | if(s[i] == s[len]) pi[i] = len + 1; 15 | } 16 | bitset ac{}; 17 | ac.set(0); 18 | for(auto i = n - 1; i > 0; i = pi[i] - 1) if(pi[i]) ac.set(n - pi[i]); 19 | return ac; 20 | } 21 | ]]> 22 | 23 | string_to_autocorrelation --> 24 | 25 | source.c++ --> 26 | 27 | -------------------------------------------------------------------------------- /Library/String/Burrows_Wheeler_Transform/burrows_wheeler_transform.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | vector burrows_wheeler_transform(const vector &s, Char_Type delim = -1){ 8 | auto sa = suffix_array(s); 9 | vector res(s.size() + 1, delim); 10 | for(auto i = 0; i <= (int)s.size(); ++ i) res[i] = sa.sa[i] ? s[sa.sa[i] - 1] : delim; 11 | return res; 12 | } 13 | // Inverse Transform 14 | // O(n) 15 | // delim must be smaller than the characters on s 16 | template 17 | vector inverse_burrows_wheeler_transform(const vector &s, Char_Type delim = -1){ 18 | int n = (int)s.size(); 19 | vector t(lim), next(n); 20 | for(auto &c: s) ++ t[c + 1]; 21 | for(auto i = 1; i < lim; ++ i) t[i] += t[i - 1]; 22 | for(auto i = 0; i < n; ++ i) next[t[s[i]] ++] = i; 23 | int cur = next[0]; 24 | vector res(n - 1, delim); 25 | for(auto i = 0; i < n - 1; ++ i) res[i] = s[cur = next[cur]]; 26 | return move(res); 27 | }; 28 | ]]> 29 | 30 | burrows_wheeler_transform --> 31 | 32 | source.c++ --> 33 | 34 | -------------------------------------------------------------------------------- /Library/String/Hash/substring_hasher.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | struct substring_hasher{ 6 | int n; 7 | vector prefix; 8 | substring_hasher(){ } 9 | // O(n) 10 | template 11 | substring_hasher(const vector &a){ build(a); } 12 | // O(n) 13 | template 14 | void build(const vector &a){ 15 | n = (int)a.size(); 16 | prefix.resize(n + 1); 17 | for(auto i = 0; i < n; ++ i) prefix[i + 1] = prefix[i] + a[i]; 18 | } 19 | // O(1) 20 | hash_t hash(int l, int r) const{ 21 | assert(0 <= l && l <= r && r <= n); 22 | return prefix[r].pop_left(prefix[l]); 23 | } 24 | }; 25 | ]]> 26 | 27 | substring_hasher --> 28 | 29 | source.c++ --> 30 | 31 | -------------------------------------------------------------------------------- /Library/String/Lyndon/lyndon_factorization.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | vector lyndon_factorization(const vector &s){ 8 | int n = (int)s.size(); 9 | vector res; 10 | for(auto i = 0; i < n; ){ 11 | int l = i, r = i + 1; 12 | for(; r < n && s[l] <= s[r]; ++ r) s[l] < s[r] ? l = i : ++ l; 13 | for(; i <= l; i += r - l) res.push_back(i); 14 | } 15 | return res; 16 | } 17 | ]]> 18 | 19 | lyndon_factorization --> 20 | 21 | source.c++ --> 22 | 23 | -------------------------------------------------------------------------------- /Library/String/Lyndon/minimal_rotation.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | int minimal_rotation(vector s){ 7 | int n = (int)s.size(), minpos = 0; 8 | for(auto i = 0; i < n; ++ i) s.push_back(s[i]); 9 | for(auto pos = 0; pos < n; ++ pos) for(auto i = 0; i < n; ++ i){ 10 | if(minpos + i == pos || s[minpos + i] < s[pos + i]){ 11 | pos += max(0, i - 1); 12 | break; 13 | } 14 | if(s[minpos + i] > s[pos + i]){ 15 | minpos = pos; 16 | break; 17 | } 18 | } 19 | return minpos; 20 | } 21 | ]]> 22 | 23 | minimal_rotation --> 24 | 25 | source.c++ --> 26 | 27 | -------------------------------------------------------------------------------- /Library/String/Main_Lorentz/main_lorentz.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | vector> main_lorentz(const vector &s){ 7 | int n = (int)s.size(); 8 | SuffixArray_t sa(s), rsa(vector{s.rbegin(), s.rend()}); 9 | RangeMinQuery_t rmq(sa.lcp), rrmq(rsa.lcp); 10 | vector> res; 11 | for(auto len = 1; len << 1 <= n; ++ len){ 12 | for(auto i = 0, last = -1; i + len <= n; i += len){ 13 | int l = i - rsa.longest_common_prefix(n - i - len, n - i, rrmq), r = i - len + sa.longest_common_prefix(i, i + len, rmq); 14 | if(l > r || l == last) continue; 15 | res.push_back({last = l, r + 1, len}); 16 | } 17 | } 18 | return res; 19 | } 20 | ]]> 21 | 22 | main_lorentz --> 23 | 24 | source.c++ --> 25 | 26 | -------------------------------------------------------------------------------- /Library/String/Manacher/manacher.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 6 | array, 2> manacher(const vector &s){ 7 | int n = (int)s.size(); 8 | array, 2> p = {vector(n + 1), vector(n)}; 9 | for(auto z = 0; z < 2; ++ z){ 10 | for(auto i = 0, l = 0, r = 0; i < n; ++ i){ 11 | int t = r - i + !z; 12 | if(i < r) p[z][i] = min(t, p[z][l + t]); 13 | int L = i - p[z][i], R = i + p[z][i] - !z; 14 | while(L >= 1 && R + 1 < n && s[L - 1] == s[R + 1]) ++ p[z][i], -- L, ++ R; 15 | if(R > r) l = L, r = R; 16 | } 17 | } 18 | return p; 19 | } 20 | ]]> 21 | 22 | manacher --> 23 | 24 | source.c++ --> 25 | 26 | -------------------------------------------------------------------------------- /Library/String/Trie/trie.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 4 | struct trie{ 5 | int n = 1; // # of active nodes(cnt != 0) 6 | vector next{{}}; 7 | vector cnt{1}; 8 | trie(){ } 9 | trie(const vector &next, const vector &cnt): n((int)next.size()), next(next), cnt(cnt){ } 10 | int extend(){ 11 | next.emplace_back(); 12 | cnt.push_back(0); 13 | return (int)next.size() - 1; 14 | } 15 | void insert(const vector &a, int u = 0){ 16 | if(!cnt[u] ++) ++ n; 17 | for(auto c: a){ 18 | if(!next[u][c]) next[u][c] = extend(); 19 | u = next[u][c]; 20 | if(!cnt[u] ++) ++ n; 21 | } 22 | } 23 | void erase(const vector &a, int u = 0){ 24 | assert(cnt[u]); 25 | if(!-- cnt[u]) -- n; 26 | for(auto c: a){ 27 | u = next[u][c]; 28 | assert(u && cnt[u]); 29 | if(!-- cnt[u]) -- n; 30 | } 31 | } 32 | int size() const{ // # of states 33 | return (int)cnt.size(); 34 | } 35 | }; 36 | ]]> 37 | 38 | trie --> 39 | 40 | source.c++ --> 41 | 42 | -------------------------------------------------------------------------------- /Library/String/Utility/count_common_substrings.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | long long count_common_substrings(const suffix_automaton &aut_s, const vector &t, const suffix_automaton &aut_t){ 8 | int m = (int)aut_t.size(); 9 | static vector req; 10 | req.assign(m, 0); 11 | int u = 0, v = 0, len = 0; 12 | for(auto c: t){ 13 | while(u && !aut_s.next[u][c]){ 14 | u = aut_s.link[u]; 15 | len = aut_s.len[u]; 16 | while(v && aut_t.max_len[aut_t.link[v]] >= len) v = aut_t.link[v]; 17 | } 18 | if(aut_s.next[u][c]){ 19 | u = aut_s.next[u][c]; 20 | ++ len; 21 | v = aut_t.next[v][c]; 22 | } 23 | req[v] = max(req[v], len); 24 | } 25 | long long res = 0; 26 | for(auto t = m - 1; t > 0; -- t){ 27 | int u = aut_t.order[t]; 28 | if(req[u]){ 29 | int v = aut_t.link[u]; 30 | res += req[u] - aut_t.max_len[v]; 31 | req[v] = max(req[v], aut_t.max_len[v]); 32 | } 33 | } 34 | req.clear(); 35 | return res; 36 | } 37 | ]]> 38 | 39 | count_common_substrings --> 40 | 41 | source.c++ --> 42 | 43 | -------------------------------------------------------------------------------- /Library/String/Utility/count_distinct_substrings.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | long long count_distinct_substrings(const vector &s){ 8 | suffix_automaton aut; 9 | aut.extend(s); 10 | long long res = 0; 11 | for(auto u = 1; u < (int)aut.size(); ++ u) res += aut.max_len[u] - aut.max_len[aut.link[u]]; 12 | return res; 13 | } 14 | ]]> 15 | 16 | count_distinct_substrings --> 17 | 18 | source.c++ --> 19 | 20 | -------------------------------------------------------------------------------- /Library/String/Utility/longest_common_substring.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 12 | array longest_common_substring(const suffix_automaton &aut, const vector &t){ 13 | int l = 0, r = 0, opt_len = 0; 14 | for(auto i = 0, u = 0, len = 0; i < (int)t.size(); ++ i){ 15 | tie(u, len) = aut.next_state(u, len, t[i]); 16 | if(opt_len < len){ 17 | opt_len = len; 18 | l = aut.firstpos[u] + 1 - len; 19 | r = i + 1 - len; 20 | } 21 | } 22 | return {opt_len, l, r}; 23 | } 24 | ]]> 25 | 26 | longest_common_substring --> 27 | 28 | source.c++ --> 29 | 30 | -------------------------------------------------------------------------------- /Library/_TEST/_TEST_bigint/a.py: -------------------------------------------------------------------------------- 1 | def read(): 2 | s = input() 3 | x = 0 4 | sign = 0 5 | i = 0 6 | while i < len(s) and (s[i] == '+' or s[i] == '-'): 7 | if s[i] == '-': 8 | sign ^= 1 9 | i += 1 10 | while i < len(s): 11 | x = x << 1 | (ord(s[i]) - ord('0')) 12 | i += 1 13 | if sign: 14 | x = -x 15 | return x 16 | def answer(x): 17 | if x == 0: 18 | print(0) 19 | return 20 | if x < 0: 21 | x = -x 22 | print('-', end = "") 23 | a = [] 24 | while x: 25 | a.append(x & 1) 26 | x = x >> 1 27 | for i in range(len(a) - 1, -1, -1): 28 | print(a[i], end = "") 29 | print() 30 | 31 | x = read() 32 | y = read() 33 | 34 | answer(x) 35 | x += 1 36 | 37 | x += 1 38 | answer(x) 39 | 40 | 41 | answer(x) 42 | x -= 1 43 | 44 | x -= 1 45 | answer(x) 46 | 47 | answer(x & y) 48 | 49 | answer(x | y) 50 | 51 | answer(x ^ y) 52 | 53 | answer(x + y) 54 | 55 | answer(x - y) 56 | 57 | answer(x * y); 58 | 59 | if y != 0: 60 | answer(x // y); 61 | 62 | answer(x % y); 63 | -------------------------------------------------------------------------------- /MarkdownPreview.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | "enable_mathjax": true, 3 | "js": [ 4 | "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js", 5 | "res://MarkdownPreview/js/math_config.js", 6 | ], 7 | "markdown_extensions": { 8 | "pymdownx.arithmatex": { 9 | "generic": true 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Package Control.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | "bootstrapped": true, 3 | "in_process_packages": 4 | [ 5 | ], 6 | "installed_packages": 7 | [ 8 | "MarkdownPreview", 9 | "Package Control", 10 | "Tact", 11 | "TypeScript Syntax" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /Preferences.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | "auto_complete_cycle": true, 3 | "auto_complete_delay": 0, 4 | "auto_complete_use_history": true, 5 | "color_scheme": "Packages/Color Scheme - Default/Celeste.sublime-color-scheme", 6 | "default_line_ending": "unix", 7 | "font_size": 8, 8 | "ignored_packages": 9 | [ 10 | "Vintage" 11 | ], 12 | "index_files": true, 13 | "shift_tab_unindent": true, 14 | "show_encoding": true, 15 | "tab_completion": false, 16 | "tab_size": 2, 17 | "theme": "Default.sublime-theme", 18 | "word_wrap": true 19 | } 20 | -------------------------------------------------------------------------------- /Python.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | "extensions": 3 | [ 4 | "sage" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /Python_completions.sublime-completions: -------------------------------------------------------------------------------- 1 | { 2 | "scope":"source.python", 3 | "completions": 4 | [ 5 | { "trigger": "io", "contents": "import sys\n\ninp = [int(x) for x in sys.stdin.read().split()]; ii = 0\n" }, 6 | ] 7 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CP 2 | 3 | Repository for maintaining CP Library 4 | -------------------------------------------------------------------------------- /SublimePrint.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | "printer_1": "Bigcloud_E9EEB9_" 3 | } 4 | --------------------------------------------------------------------------------