├── .cargo └── config.toml ├── .github └── workflows │ ├── doc_test.yml │ ├── fail.yml │ ├── gen_doc.yml │ ├── gen_mirror.yml │ ├── pr_doc_test.yml │ ├── prep_testcase.yml │ ├── unit_test.yml │ └── verify.yml ├── .gitignore ├── Cargo.toml ├── LICENSE ├── README.md ├── clippy.toml ├── crates ├── algo │ ├── bisect_ │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── exact_cover │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── extremum │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── extremum_float │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── hilbert_mo_ │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── index_order │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── inversion │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── karatsuba │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── larsch │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── majority_ │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── minmax │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── mo │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── ordered_hash_ │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── parallel_bisect │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── permutation │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── rle │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── tortoise_hare │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ └── window_bisect │ │ ├── Cargo.toml │ │ └── src │ │ └── lib.rs ├── ds │ ├── bicremental_median │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── bicremental_median_dev │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── binary_trie │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── bit_set │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── btree_bimap │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── btree_multiset │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── cuckoo_hash_map │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── cuckoo_hash_set │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── decremental_usize_set │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── disjoint_sparse_table │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── foldable_deque │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── foldable_queue │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── incremental_line_set │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── interval_map │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── interval_set │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── lib.rs │ │ │ └── main.rs │ ├── n1_rmq │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── potentialized_union_find │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── range_tree │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── removable_heap │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── rs_dict │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── skew_heap │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── union_find │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── vec_act_segtree │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── lib.rs │ │ │ └── main.rs │ ├── vec_segtree │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ └── wavelet_matrix │ │ ├── Cargo.toml │ │ └── src │ │ └── lib.rs ├── graph │ ├── adjlist │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── dijkstra │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── dijkstra_ │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── dinic_ │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── functional_graph │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── hld │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── scc_ │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── sssp │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ └── tree_cata │ │ ├── Cargo.toml │ │ └── src │ │ └── lib.rs ├── math │ ├── bit_binom_ │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── carmichael_lambda │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── common_quot │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── compact_sieve │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── const_div │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── continued_fraction_ │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── convolution │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── count_prime │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── crt │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── digit_sum │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── digits │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── divisors │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── dlog │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── equiv_mod │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── euler_phi │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── factors │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── factors_dup │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── frac_approx │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── fraction_bisect │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── garner │ │ ├── Cargo.toml │ │ ├── src │ │ │ └── lib.rs │ │ └── test.py │ ├── gcd │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── gcd_recip │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── harmonic_floor_sum │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── interpolation │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── is_close_float │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── lcm │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── linear_floor_sum │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── linear_sieve │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── miller_rabin │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── mod_ackermann │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── mod_factorial_binom │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── mod_ord │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── mod_pow │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── mod_recip_table_ │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── mod_tetration │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── modint │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── _lib.rs │ │ │ └── lib.rs │ ├── polynomial │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── prime_pi_ │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── segmented_factor_sieve │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── sieve_n2_plus_1 │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── sieve_n2_plus_n_plus_1 │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── slope_function │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── sqrt │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── sqrt_fraction_ │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── stern_brocot_ │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ └── two_sat │ │ ├── Cargo.toml │ │ └── src │ │ └── lib.rs ├── seq │ ├── kmp │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── lib.rs │ │ │ └── main.rs │ ├── suffix_array │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── lib.rs │ │ │ └── main.rs │ └── z_algo │ │ ├── Cargo.toml │ │ └── src │ │ └── lib.rs ├── traits │ ├── act │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── action │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── additive │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── binop │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── bisect │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── count │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── disjoint-set │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── elastic_slice │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── find_nth │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── fold │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── fold_bisect │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── get_mut │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── group_by │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── max │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── min │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── multiplicative │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── pat_searcher │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── potential_function │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── push_pop │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── quantile │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── range_bounds │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── set_value │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── stateful_predicate │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ └── usize_group_by │ │ ├── Cargo.toml │ │ └── src │ │ └── lib.rs └── utils │ ├── ascii │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── bitop │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── buf_range │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── e_macro │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── hexdump │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── make_minmax │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── op_add │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── op_add_count │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── op_add_on_op_add_count │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── op_add_on_op_max │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── op_add_on_op_min │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── op_affine │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── op_affine_on_op_add_count │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── op_closure │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── op_closure_on_op_closure │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── op_gcd │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── op_max │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── op_min │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── op_mul │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── op_roll_hash │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── output │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── rand_gen_macro │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── scan_macro │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ └── scanner │ ├── Cargo.toml │ └── src │ └── lib.rs ├── katex-header.html ├── notes ├── Cargo.toml └── src │ └── lib.rs ├── script ├── Cargo.toml └── src │ └── bin │ └── revision-art.rs ├── static ├── .cargo │ └── config.toml ├── Cargo.toml ├── clippy.toml ├── ferris-in-doc.html ├── images │ └── tree_cata.png ├── katex-header.html ├── lato-header.html ├── nekolib-notes │ ├── Cargo.toml │ ├── debug.md │ ├── ferris-in-doc.html │ ├── katex-header.html │ ├── lato-header.html │ └── src │ │ ├── debug.rs │ │ ├── lib.rs │ │ └── range_add_on_the_fly.rs ├── nekolib-verify │ ├── Cargo.toml │ ├── ferris-in-doc.html │ ├── katex-header.html │ ├── lato-header.html │ └── src │ │ └── lib.rs ├── nekolib │ ├── Cargo.toml │ ├── ferris-in-doc.html │ ├── katex-header.html │ ├── lato-header.html │ └── src │ │ ├── algo.rs │ │ ├── ds.rs │ │ ├── graph.rs │ │ ├── lib.rs │ │ ├── math.rs │ │ ├── seq.rs │ │ ├── traits.rs │ │ └── utils.rs └── poem.md └── verifiers ├── .gitignore ├── download ├── Cargo.toml └── src │ ├── lib.rs │ └── main.rs └── verify ├── Cargo.toml ├── src ├── jury.rs ├── jury │ ├── aoj_0000.rs │ ├── aoj_0002.rs │ ├── aoj_0270.rs │ ├── aoj_0425.rs │ ├── aoj_0564.rs │ ├── aoj_0575.rs │ ├── aoj_1180.rs │ ├── aoj_2880.rs │ ├── aoj_alds1_14_b.rs │ ├── aoj_alds1_14_d.rs │ ├── aoj_dsl_1_a.rs │ ├── aoj_dsl_1_b.rs │ ├── aoj_dsl_2_b.rs │ ├── aoj_dsl_2_d.rs │ ├── aoj_grl_1_a.rs │ ├── aoj_grl_3_c.rs │ ├── aoj_grl_6_a.rs │ ├── template.rs │ ├── yuki_1601.rs │ └── yuki_3287.rs ├── lib.rs ├── solver.rs ├── solver │ ├── aoj_0000.rs │ ├── aoj_0000_re.rs │ ├── aoj_0000_tle.rs │ ├── aoj_0000_wa.rs │ ├── aoj_0002.rs │ ├── aoj_0270.rs │ ├── aoj_0425.rs │ ├── aoj_0564.rs │ ├── aoj_0575.rs │ ├── aoj_1180.rs │ ├── aoj_2880.rs │ ├── aoj_alds1_14_b.rs │ ├── aoj_alds1_14_b_kmp.rs │ ├── aoj_alds1_14_b_z.rs │ ├── aoj_alds1_14_d.rs │ ├── aoj_dsl_1_a.rs │ ├── aoj_dsl_1_b.rs │ ├── aoj_dsl_2_b.rs │ ├── aoj_dsl_2_d_iset.rs │ ├── aoj_grl_1_a.rs │ ├── aoj_grl_3_c.rs │ ├── aoj_grl_6_a.rs │ ├── template.rs │ ├── yuki_1601.rs │ └── yuki_3287.rs └── test_set.rs └── tests ├── test_judge.rs ├── verify.rs ├── verify_interval_set.rs ├── verify_suffix_array.rs └── verify_vec_segtree.rs /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | # See https://doc.rust-lang.org/cargo/reference/config.html 2 | 3 | [alias] 4 | d = "doc" 5 | p = "clippy -- -W clippy::pedantic -A clippy::doc_markdown -A clippy::module_name_repetitions" 6 | 7 | [build] 8 | # Comment out next line when you run `cargo test`. 9 | # rustdocflags = ["--html-in-header", "katex-header.html"] 10 | -------------------------------------------------------------------------------- /.github/workflows/doc_test.yml: -------------------------------------------------------------------------------- 1 | name: test --doc 2 | 3 | on: 4 | push: 5 | branches: 6 | - doc 7 | paths: 8 | - 'trigger/doc_test' 9 | workflow_dispatch: 10 | 11 | jobs: 12 | test: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | with: 18 | ref: doc 19 | path: doc 20 | 21 | - name: Install latest Rust toolchain 22 | uses: actions-rs/toolchain@v1 23 | with: 24 | toolchain: stable 25 | override: true 26 | 27 | - name: Test doc 28 | run: | 29 | cd doc/gen/generated 30 | cargo t --doc 31 | -------------------------------------------------------------------------------- /.github/workflows/fail.yml: -------------------------------------------------------------------------------- 1 | name: fail 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | status: 7 | type: choice 8 | options: 9 | - passing 10 | - failing 11 | 12 | jobs: 13 | perform: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Fail 18 | run: | 19 | status=${{ github.event.inputs.status }} 20 | if [[ "${status:-failing}" == passing ]]; then 21 | true 22 | else 23 | false 24 | fi 25 | -------------------------------------------------------------------------------- /.github/workflows/gen_doc.yml: -------------------------------------------------------------------------------- 1 | name: generate document 2 | 3 | on: 4 | push: 5 | branches: 6 | - doc 7 | paths: 8 | - 'trigger/gen_doc' 9 | workflow_dispatch: 10 | 11 | jobs: 12 | generate: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | with: 18 | ref: doc 19 | path: doc 20 | 21 | - uses: actions/checkout@v2 22 | with: 23 | repository: rsk0315/rsk0315.github.io 24 | path: gh 25 | token: ${{ secrets.GH_TOKEN }} 26 | 27 | - name: Install latest Rust toolchain 28 | uses: actions-rs/toolchain@v1 29 | with: 30 | toolchain: stable 31 | override: true 32 | 33 | - name: Generate doc 34 | run: | 35 | rm -Rf gh/library-rs 36 | mkdir gh/library-rs 37 | cd doc/gen/generated 38 | cargo d 39 | cd target/doc 40 | cp -R * ../../../../../gh/library-rs/ 41 | cd ../../../../../gh/library-rs 42 | git add . 43 | git config user.name github-actions 44 | git config user.email github-actions@github.com 45 | git commit -m '[auto-generated]' || true 46 | 47 | - name: Push to github.io 48 | uses: cpina/github-action-push-to-another-repository@main 49 | env: 50 | API_TOKEN_GITHUB: ${{ secrets.GH_TOKEN }} 51 | with: 52 | source-directory: gh 53 | destination-github-username: 'rsk0315' 54 | destination-repository-name: 'rsk0315.github.io' 55 | user-name: 'github-actions' 56 | user-email: 'github-actions@github.com' 57 | target-branch: master 58 | -------------------------------------------------------------------------------- /.github/workflows/pr_doc_test.yml: -------------------------------------------------------------------------------- 1 | name: pr doctest 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize] 6 | workflow_dispatch: 7 | 8 | jobs: 9 | test: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | with: 15 | # スクリプトが master/ を読むことになっている... 16 | path: master 17 | 18 | - uses: actions/checkout@v2 19 | with: 20 | ref: doc 21 | path: doc 22 | 23 | - name: Install latest Rust toolchain 24 | uses: actions-rs/toolchain@v1 25 | with: 26 | toolchain: stable 27 | override: true 28 | 29 | - name: Generate mirror 30 | run: | 31 | pwd 32 | [[ -d doc/gen/generated ]] && rm -Rf doc/gen/generated 33 | cd master/script 34 | cargo run --bin revision-art ${GITHUB_SHA} >> ../static/nekolib/src/lib.rs 35 | cd ../.. 36 | mkdir -p doc/gen 37 | cp -R master/static doc/gen/generated 38 | cd doc/gen 39 | ls 40 | cargo run --release 41 | 42 | - name: Test documents 43 | run: | 44 | pwd 45 | cd doc/gen/generated 46 | cargo d 47 | cd target/doc 48 | ls 49 | cd - 50 | cargo t --doc 51 | -------------------------------------------------------------------------------- /.github/workflows/prep_testcase.yml: -------------------------------------------------------------------------------- 1 | name: prepare testcases 2 | on: 3 | push: 4 | branches: 5 | - master 6 | paths: 7 | - 'verifiers/download/src/main.rs' 8 | workflow_dispatch: 9 | 10 | jobs: 11 | prepare: 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | 17 | - uses: actions/checkout@v2 18 | with: 19 | repository: rsk0315/oj-testcases-mirror 20 | token: ${{ secrets.GH_TOKEN }} 21 | path: oj-testcases-mirror 22 | 23 | - name: Download testcase 24 | env: 25 | YUKICODER_TOKEN: ${{ secrets.YUKICODER_TOKEN }} 26 | run: | 27 | if [[ -d oj-testcases-mirror/testcases ]]; then 28 | mv oj-testcases-mirror/testcases verifiers/ 29 | else 30 | mkdir verifiers/testcases 31 | fi 32 | cd verifiers/download 33 | cargo run 34 | cd ../.. 35 | mv verifiers/testcases oj-testcases-mirror/ 36 | cd oj-testcases-mirror 37 | git add . 38 | git config user.name github-actions 39 | git config user.email github-actions@github.com 40 | git commit -m '[auto-generated]' || true 41 | 42 | - name: Push to mirror 43 | uses: cpina/github-action-push-to-another-repository@master 44 | env: 45 | API_TOKEN_GITHUB: ${{ secrets.GH_TOKEN }} 46 | with: 47 | source-directory: oj-testcases-mirror 48 | destination-github-username: rsk0315 49 | destination-repository-name: oj-testcases-mirror 50 | user-email: github-actions@github.com 51 | target-branch: main 52 | -------------------------------------------------------------------------------- /.github/workflows/unit_test.yml: -------------------------------------------------------------------------------- 1 | name: test --lib 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | paths: 8 | - '.github/workflows/unit_test.yml' 9 | - 'crates/**' 10 | pull_request: 11 | types: [opened, synchronize] 12 | workflow_dispatch: 13 | 14 | jobs: 15 | test: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v2 20 | 21 | - name: Install latest Rust toolchain 22 | uses: actions-rs/toolchain@v1 23 | with: 24 | toolchain: stable 25 | override: true 26 | 27 | - name: Test lib 28 | run: | 29 | cd crates 30 | cargo test --release --lib 31 | -------------------------------------------------------------------------------- /.github/workflows/verify.yml: -------------------------------------------------------------------------------- 1 | name: verify 2 | on: 3 | push: 4 | branches: 5 | - master 6 | paths: 7 | - '.github/workflows/verify.yml' 8 | - '.cargo/config.toml' 9 | - 'Cargo.toml' 10 | - 'crates/**' 11 | - 'verifiers/**' 12 | pull_request: 13 | types: [opened, synchronize] 14 | workflow_dispatch: 15 | 16 | jobs: 17 | verify: 18 | runs-on: ubuntu-latest 19 | 20 | steps: 21 | - uses: actions/checkout@v2 22 | 23 | - uses: actions/checkout@v2 24 | with: 25 | repository: rsk0315/oj-testcases-mirror 26 | token: ${{ secrets.GH_TOKEN }} 27 | path: oj-testcases-mirror 28 | 29 | - name: Prepare testcases 30 | run: | 31 | mv oj-testcases-mirror/testcases verifiers/ 32 | 33 | - name: Verify 34 | run: | 35 | cd verifiers/verify 36 | cargo test --release 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | target/ 4 | 5 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 6 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 7 | Cargo.lock 8 | 9 | # These are backup files generated by rustfmt 10 | **/*.rs.bk 11 | 12 | # Backup files 13 | *~ 14 | .DS_Store 15 | 16 | # Testcases 17 | testcases/ 18 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | 'crates/algo/*/', 4 | 'crates/ds/*/', 5 | 'crates/graph/*/', 6 | 'crates/math/*/', 7 | 'crates/seq/*/', 8 | 'crates/traits/*/', 9 | 'crates/utils/*/', 10 | 'verifiers/download', 11 | 'verifiers/verify', 12 | 'notes/', 13 | ] 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 rsk0315 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # library-rs 2 | 3 | ![verify](https://github.com/rsk0315/library-rs/workflows/verify/badge.svg) 4 | [![doctest](https://github.com/rsk0315/library-rs/workflows/test%20--doc/badge.svg)](https://rsk0315.github.io/library-rs/nekolib/) 5 | [![unittest](https://github.com/rsk0315/library-rs/workflows/test%20--lib/badge.svg)](https://github.com/rsk0315/library-rs/actions/workflows/unit_test.yml) 6 | [![rsk0315](https://img.shields.io/endpoint?url=https%3A%2F%2Fatcoder-badges.now.sh%2Fapi%2Fatcoder%2Fjson%2Frsk0315)](https://atcoder.jp/users/rsk0315) 7 | 8 | Rust のライブラリです。 9 | 10 | 競プロ用という建前をしつつ、自分が気持ちよくなることためのライブラリです。 11 | 意味論にこだわったりドキュメントを書いたりして気持ちよくなりたいです。 12 | 13 | ドキュメントは [こちら](https://rsk0315.github.io/library-rs/nekolib/)。 14 | -------------------------------------------------------------------------------- /clippy.toml: -------------------------------------------------------------------------------- 1 | single-char-binding-names-threshold = 20 2 | type-complexity-threshold = 10000 3 | -------------------------------------------------------------------------------- /crates/algo/bisect_/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bisect_" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/algo/exact_cover/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "exact_cover" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/algo/extremum/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "extremum" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/algo/extremum_float/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "extremum_float" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/algo/hilbert_mo_/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hilbert_mo_" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | elastic_slice = { path = "../../traits/elastic_slice" } 10 | 11 | -------------------------------------------------------------------------------- /crates/algo/index_order/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "index_order" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/algo/inversion/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "inversion" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/algo/inversion/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub trait Inversion { 2 | fn inversion(&self) -> u64; 3 | } 4 | 5 | impl Inversion for [T] { 6 | fn inversion(&self) -> u64 { 7 | let n = self.len(); 8 | let ord = { 9 | let mut ord: Vec<_> = (0..n).collect(); 10 | ord.sort_unstable_by(|&il, &ir| { 11 | self[il].cmp(&self[ir]).then_with(|| il.cmp(&ir)) 12 | }); 13 | ord 14 | }; 15 | 16 | let mut res = 0; 17 | let mut sum = vec![0; n + 1]; 18 | for i in ord.iter().map(|&i| i + 1) { 19 | { 20 | let mut i = i; 21 | while i <= n { 22 | res += sum[i]; 23 | i += i & i.wrapping_neg(); 24 | } 25 | } 26 | { 27 | let mut i = i; 28 | while i > 0 { 29 | sum[i] += 1; 30 | i -= i & i.wrapping_neg(); 31 | } 32 | } 33 | } 34 | 35 | res 36 | } 37 | } 38 | 39 | #[test] 40 | fn sanity_check() { 41 | assert_eq!([1, 5, 4, 2, 3].inversion(), 5); 42 | assert_eq!([1, 2, 3, 4, 5].inversion(), 0); 43 | assert_eq!([5, 4, 3, 2, 1].inversion(), 10); 44 | assert_eq!([1, 1, 1, 1, 1].inversion(), 0); 45 | 46 | let empty: [(); 0] = []; 47 | assert_eq!(empty.inversion(), 0); 48 | } 49 | -------------------------------------------------------------------------------- /crates/algo/karatsuba/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "karatsuba" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/algo/larsch/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "larsch" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/algo/majority_/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "majority_" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/algo/majority_/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Boyer--Moore's majority vote algorithm。 2 | 3 | /// Boyer--Moore's majority vote algorithm。 4 | /// 5 | /// 過半数の出現数を持つ要素があれば、それを返す。 6 | /// 7 | /// # Idea 8 | /// `todo!()` 9 | /// 10 | /// # Complexity 11 | /// $O(n)$ time. 12 | /// 13 | /// # Examples 14 | /// ``` 15 | /// use nekolib::algo::majority; 16 | /// 17 | /// assert_eq!(majority(&[1, 1, 3, 2, 1]), Some(&1)); 18 | /// assert_eq!(majority(&[9]), Some(&9)); 19 | /// assert_eq!(majority(&[6, 7]), None); 20 | /// assert_eq!(majority::(&[]), None); 21 | /// ``` 22 | pub fn majority(buf: &[T]) -> Option<&T> { 23 | if buf.is_empty() { 24 | return None; 25 | } 26 | let mut maj = &buf[0]; 27 | let mut vote = 1; 28 | let n = buf.len(); 29 | for x in buf.iter().skip(1) { 30 | if maj == x { 31 | vote += 1; 32 | } else if vote == 0 { 33 | maj = x; 34 | vote = 1; 35 | } else { 36 | vote -= 1; 37 | } 38 | } 39 | let mut vote = 0; 40 | let mut first = 0; 41 | for (i, x) in buf.iter().enumerate().rev() { 42 | if maj == x { 43 | vote += 1; 44 | first = i; 45 | } 46 | } 47 | if vote > n - vote { 48 | Some(&buf[first]) 49 | } else { 50 | None 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /crates/algo/minmax/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "minmax" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/algo/mo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mo" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | elastic_slice = { path = "../../traits/elastic_slice" } 11 | sqrt = { path = "../../math/sqrt" } 12 | -------------------------------------------------------------------------------- /crates/algo/ordered_hash_/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ordered_hash_" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/algo/ordered_hash_/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 座標圧縮。 2 | 3 | use std::collections::{BTreeMap, BTreeSet}; 4 | 5 | /// 座標圧縮。 6 | /// 7 | /// # Examples 8 | /// ``` 9 | /// use nekolib::algo::ordered_hash; 10 | /// 11 | /// let oh = ordered_hash(&[0, 1, 3, 1, 5]); 12 | /// assert_eq!(oh.len(), 4); 13 | /// assert_eq!(oh[&0], 0); 14 | /// assert_eq!(oh[&1], 1); 15 | /// assert_eq!(oh[&3], 2); 16 | /// assert_eq!(oh[&5], 3); 17 | /// ``` 18 | pub fn ordered_hash<'a, K: Ord>(buf: &'a [K]) -> BTreeMap<&'a K, usize> { 19 | let set: BTreeSet<_> = buf.iter().collect(); 20 | set.into_iter().zip(0..).collect() 21 | } 22 | -------------------------------------------------------------------------------- /crates/algo/parallel_bisect/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "parallel_bisect" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | stateful_predicate = { path = "../../traits/stateful_predicate" } 11 | -------------------------------------------------------------------------------- /crates/algo/permutation/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "permutation" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/algo/rle/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rle" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/algo/tortoise_hare/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tortoise_hare" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/algo/window_bisect/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "window_bisect" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | elastic_slice = { path = "../../traits/elastic_slice" } 11 | -------------------------------------------------------------------------------- /crates/ds/bicremental_median/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bicremental_median" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/ds/bicremental_median_dev/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bicremental_median_dev" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | binop = { path = "../../traits/binop" } 11 | 12 | [dev-dependencies] 13 | op_add = { path = "../../utils/op_add" } 14 | -------------------------------------------------------------------------------- /crates/ds/binary_trie/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "binary_trie" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/ds/bit_set/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bit_set" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | buf_range = { path = "../../utils/buf_range" } 10 | -------------------------------------------------------------------------------- /crates/ds/btree_bimap/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "btree_bimap" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/ds/btree_multiset/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "btree_multiset" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/ds/cuckoo_hash_map/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cuckoo_hash_map" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/ds/cuckoo_hash_set/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cuckoo_hash_set" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | cuckoo_hash_map = { path = "../cuckoo_hash_map" } 10 | -------------------------------------------------------------------------------- /crates/ds/cuckoo_hash_set/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! `CuckooHashMap` の wrapper。 2 | 3 | use std::hash::Hash; 4 | use std::iter::FromIterator; 5 | 6 | use cuckoo_hash_map::CuckooHashMap; 7 | 8 | /// `CuckooHashMap` の wrapper。 9 | #[derive(Clone, Debug)] 10 | pub struct CuckooHashSet(CuckooHashMap); 11 | 12 | impl CuckooHashSet { 13 | pub fn new() -> Self { Self(CuckooHashMap::new()) } 14 | pub fn contains(&self, key: &K) -> bool { self.0.contains_key(key) } 15 | pub fn insert(&mut self, key: K) -> bool { 16 | self.0.insert(key, ()).is_none() 17 | } 18 | pub fn remove(&mut self, key: &K) -> bool { self.0.remove(key).is_some() } 19 | pub fn len(&self) -> usize { self.0.len() } 20 | pub fn is_empty(&self) -> bool { self.0.is_empty() } 21 | } 22 | 23 | impl FromIterator for CuckooHashSet { 24 | fn from_iter(iter: I) -> Self 25 | where 26 | I: IntoIterator, 27 | { 28 | let mut res = CuckooHashSet::new(); 29 | for k in iter { 30 | res.insert(k); 31 | } 32 | res 33 | } 34 | } 35 | 36 | impl Extend for CuckooHashSet { 37 | fn extend(&mut self, iter: I) 38 | where 39 | I: IntoIterator, 40 | { 41 | for k in iter { 42 | self.insert(k); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /crates/ds/decremental_usize_set/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "decremental_usize_set" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/ds/disjoint_sparse_table/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "disjoint_sparse_table" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | fold = { path = "../../traits/fold" } 11 | binop = { path = "../../traits/binop" } 12 | buf_range = { path = "../../utils/buf_range" } 13 | -------------------------------------------------------------------------------- /crates/ds/foldable_deque/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "foldable_deque" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | binop = { path = "../../traits/binop" } 11 | fold = { path = "../../traits/fold" } 12 | push_pop = { path = "../../traits/push_pop" } 13 | -------------------------------------------------------------------------------- /crates/ds/foldable_queue/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "foldable_queue" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | binop = { path = "../../traits/binop" } 11 | fold = { path = "../../traits/fold" } 12 | push_pop = { path = "../../traits/push_pop" } 13 | -------------------------------------------------------------------------------- /crates/ds/incremental_line_set/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "incremental_line_set" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | btree_bimap = { path = "../btree_bimap" } 10 | -------------------------------------------------------------------------------- /crates/ds/interval_map/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "interval_map" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/ds/interval_set/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "interval_set" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/ds/n1_rmq/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "n1_rmq" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/ds/potentialized_union_find/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "potentialized_union_find" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | binop = { path = "../../traits/binop" } 11 | potential_function = { path = "../../traits/potential_function" } 12 | -------------------------------------------------------------------------------- /crates/ds/range_tree/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "range_tree" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/ds/range_tree/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused)] 2 | 3 | use std::collections::BTreeMap; 4 | 5 | pub struct RangeTree { 6 | buf: Vec, 7 | occ: BTreeMap>, 8 | ind: RangeTreeUsize, 9 | val: RangeTreeUsize, 10 | } 11 | 12 | impl From> for RangeTree { 13 | fn from(buf: Vec) -> Self { 14 | let occ = { 15 | let mut occ = BTreeMap::new(); 16 | for (i, x) in buf.iter().cloned().enumerate() { 17 | occ.entry(x).or_insert(vec![]).push(i); 18 | } 19 | occ 20 | }; 21 | let n = buf.len(); 22 | let ind = { 23 | let mut ind = vec![0; n]; 24 | let mut enc_x = 0; 25 | for v in occ.values() { 26 | for &i in v { 27 | ind[i] = enc_x; 28 | enc_x += 1; 29 | } 30 | } 31 | ind 32 | }; 33 | let val = { 34 | let mut val = vec![0; n]; 35 | for i in 0..n { 36 | val[ind[i]] = i; 37 | } 38 | val 39 | }; 40 | let ind: RangeTreeUsize = ind.into(); 41 | let val: RangeTreeUsize = val.into(); 42 | Self { buf, occ, ind, val } 43 | } 44 | } 45 | 46 | // Count 47 | // Count3way 48 | // Quantile 49 | // FindNth 50 | 51 | struct RangeTreeUsize { 52 | casc: Vec>, 53 | down: Vec>, 54 | } 55 | 56 | impl From> for RangeTreeUsize { 57 | fn from(buf: Vec) -> Self { 58 | let casc = vec![]; 59 | let down = vec![]; 60 | Self { casc, down } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /crates/ds/removable_heap/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "removable_heap" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/ds/rs_dict/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rs_dict" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | buf_range = { path = "../../utils/buf_range" } 11 | count = { path = "../../traits/count" } 12 | find_nth = { path = "../../traits/find_nth" } 13 | -------------------------------------------------------------------------------- /crates/ds/skew_heap/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "skew_heap" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/ds/union_find/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "union-find" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | disjoint-set = { path = "../../traits/disjoint-set" } 11 | -------------------------------------------------------------------------------- /crates/ds/vec_act_segtree/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "vec_act_segtree" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | act = { path = "../../traits/act" } 11 | action = { path = "../../traits/action" } 12 | binop = { path = "../../traits/binop" } 13 | buf_range = { path = "../../utils/buf_range" } 14 | fold = { path = "../../traits/fold" } 15 | fold_bisect = { path = "../../traits/fold_bisect" } 16 | get_mut = { path = "../../traits/get_mut" } 17 | 18 | [dev-dependencies] 19 | op_max = { path = "../../utils/op_max" } 20 | op_add = { path = "../../utils/op_add" } 21 | min = { path = "../../traits/min" } 22 | additive = { path = "../../traits/additive" } 23 | op_closure = { path = "../../utils/op_closure" } 24 | op_closure_on_op_closure = { path = "../../utils/op_closure_on_op_closure" } 25 | op_affine_on_op_add_count = { path = "../../utils/op_affine_on_op_add_count" } 26 | -------------------------------------------------------------------------------- /crates/ds/vec_segtree/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "vec_segtree" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | binop = { path = "../../traits/binop" } 11 | fold = { path = "../../traits/fold" } 12 | fold_bisect = { path = "../../traits/fold_bisect" } 13 | set_value = { path = "../../traits/set_value" } 14 | buf_range = { path = "../../utils/buf_range" } 15 | get_mut = { path = "../../traits/get_mut" } 16 | 17 | [dev-dependencies] 18 | op_add = { path = "../../utils/op_add" } 19 | -------------------------------------------------------------------------------- /crates/ds/wavelet_matrix/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wavelet_matrix" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | rs_dict = { path = "../rs_dict" } 11 | count = { path = "../../traits/count" } 12 | find_nth = { path = "../../traits/find_nth" } 13 | buf_range = { path = "../../utils/buf_range" } 14 | quantile = { path = "../../traits/quantile" } 15 | -------------------------------------------------------------------------------- /crates/graph/adjlist/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "adjlist" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/graph/adjlist/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::collections::VecDeque; 2 | 3 | pub fn from_root( 4 | n: usize, 5 | es: &[(usize, usize, T)], 6 | r: usize, 7 | ) -> Vec> { 8 | let mut g = vec![vec![]; n]; 9 | for &(u, v, ref w) in es { 10 | g[u].push((v, w.clone())); 11 | g[v].push((u, w.clone())); 12 | } 13 | 14 | let mut res = vec![vec![]; n]; 15 | let mut q = VecDeque::new(); 16 | let mut seen = vec![false; n]; 17 | q.push_back(r); 18 | seen[r] = true; 19 | while let Some(v) = q.pop_front() { 20 | for (nv, nw) in g[v].drain(..) { 21 | if seen[nv] { 22 | continue; 23 | } 24 | seen[nv] = true; 25 | res[v].push((nv, nw)); 26 | q.push_back(nv); 27 | } 28 | } 29 | res 30 | } 31 | -------------------------------------------------------------------------------- /crates/graph/dijkstra/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dijkstra" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | sssp = { path = "../sssp" } 10 | -------------------------------------------------------------------------------- /crates/graph/dijkstra_/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dijkstra_" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/graph/dinic_/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dinic_" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/graph/functional_graph/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "functional_graph" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/graph/hld/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hld" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/graph/scc_/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "scc_" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/graph/sssp/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sssp" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/graph/sssp/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub trait Sssp { 2 | type Cost; 3 | type Path: Iterator; 4 | fn cost(&self, dst: &V) -> Option; 5 | fn path(&self, dst: &V) -> Self::Path; 6 | } 7 | -------------------------------------------------------------------------------- /crates/graph/tree_cata/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tree_cata" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/math/bit_binom_/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bit_binom_" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/math/bit_binom_/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 組合せのビット表現。 2 | 3 | /// 組合せのビット表現。 4 | /// 5 | /// $n$ bit で表せる整数のうち、$k$ 個の bit が `1` であるものを昇順に生成する。 6 | /// 7 | /// # Idea 8 | /// 9 | /// $k$ 個の bit が `1` である整数 `i` が与えられたとき、$k$ 個の bit が `1` 10 | /// である整数のうち `i` より大きく最小の整数 `j` を考える。 11 | /// 12 | /// 例として `i = 011001110` とする。 13 | /// ```text 14 | /// 011001110 // i 15 | /// ^~~~ 16 | /// ``` 17 | /// `i` のうちで `1` が連続して現れる部分のうち、最も右のものを考える。 18 | /// これの左にある `0` の位は、`j` においては `1` である必要がある。 19 | /// ```text 20 | /// 011001110 // i 21 | /// 01101.... // j (upper) 22 | /// ``` 23 | /// また、残った下位の領域においては、`i` における `1` の連続個数よりひとつ少ない 24 | /// `1` を右詰めで入れればよい。 25 | /// ```text 26 | /// 011001110 // i 27 | /// .....0011 // j (lower) 28 | /// ``` 29 | /// 30 | /// あとは、これらを計算する方法について述べる。 31 | /// ```text 32 | /// 011001110 // i 33 | /// 000000010 // x = i & i.wrapping_neg() 34 | /// 011010000 // y = i + x 35 | /// 000001110 // i & !y 36 | /// 000000011 // z = (i & !y) >> (x.trailing_zeros() + 1) 37 | /// 011010011 // j = y | z 38 | /// ``` 39 | /// 上記では `_ >> (x.trailing_zeros() + 1)` としているが、`x` が 2 40 | /// べきなので `(_ / x) >> 1` と等しい。 41 | /// 42 | /// # Examples 43 | /// ``` 44 | /// use nekolib::math::bit_binom; 45 | /// 46 | /// let mut it = bit_binom(4, 2); 47 | /// assert_eq!(it.next(), Some(0b_0011)); 48 | /// assert_eq!(it.next(), Some(0b_0101)); 49 | /// assert_eq!(it.next(), Some(0b_0110)); 50 | /// assert_eq!(it.next(), Some(0b_1001)); 51 | /// assert_eq!(it.next(), Some(0b_1010)); 52 | /// assert_eq!(it.next(), Some(0b_1100)); 53 | /// assert_eq!(it.next(), None); 54 | /// ``` 55 | /// 56 | /// # References 57 | /// - 蟻本 p.144 58 | pub fn bit_binom(n: usize, k: usize) -> impl Iterator { 59 | std::iter::successors(Some(!(!0_usize << k)), move |&i| { 60 | if k == 0 { 61 | return None; 62 | } 63 | let x = i & i.wrapping_neg(); 64 | let y = i + x; 65 | let z = (i & !y) >> (x.trailing_zeros() + 1); 66 | Some(y | z) 67 | }) 68 | .take_while(move |&i| i < (1_usize << n)) 69 | } 70 | -------------------------------------------------------------------------------- /crates/math/carmichael_lambda/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "carmichael_lambda" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | factors = { path = "../factors" } 11 | lcm = { path = "../lcm" } 12 | 13 | [dev-dependencies] 14 | gcd = { path = "../gcd" } 15 | -------------------------------------------------------------------------------- /crates/math/common_quot/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "common_quot" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/math/compact_sieve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "compact_sieve" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/math/compact_sieve/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 篩。 2 | 3 | /// 篩。 4 | pub struct CompactSieve { 5 | n: usize, 6 | is_prime: Vec, 7 | } 8 | 9 | const WORD_SIZE: usize = 64; 10 | 11 | impl CompactSieve { 12 | pub fn new(n: usize) -> Self { 13 | let mut is_prime = vec![0xAAAAAAAAAAAAAAAA; 1 + n / WORD_SIZE]; 14 | is_prime[0] |= 1 << 2; 15 | for i in (3..=n).take_while(|&i| i * i <= n) { 16 | if is_prime[i / WORD_SIZE] >> (i % WORD_SIZE) & 1 == 0 { 17 | continue; 18 | } 19 | for j in i..=n / i { 20 | let ij = i * j; 21 | is_prime[ij / WORD_SIZE] &= !(1_u64 << (ij % WORD_SIZE)); 22 | } 23 | } 24 | Self { n, is_prime } 25 | } 26 | pub fn is_prime(&self, i: usize) -> bool { 27 | self.is_prime[i / WORD_SIZE] >> (i % WORD_SIZE) & 1 == 1 28 | } 29 | pub fn primes(&self) -> impl Iterator + '_ { 30 | (2..=self.n).filter(move |&i| self.is_prime(i)) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /crates/math/const_div/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "const_div" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/math/continued_fraction_/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "continued_fraction_" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/math/continued_fraction_/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 連分数展開。 2 | 3 | /// 連分数展開。 4 | /// 5 | /// $[a\_0, a\_1, \\dots, a\_{i-1}]$ の連分数展開。 6 | /// $a\_\\bullet$ を生成するイテレータから 7 | /// $$ 8 | /// a\_0 + \\frac{1}{a\_1 + \\frac{1}{\\cdots\\, + \\frac{1}{a\_{\\bullet}}}} 9 | /// $$ 10 | /// を生成するイテレータを作る。 11 | /// 12 | /// # Implementation notes 13 | /// [`std::iter::successors`](https://doc.rust-lang.org/std/iter/fn.successors.html) 14 | /// によって次の項が計算されるタイミングの関係で、 15 | /// 実際には必要ない値の計算のせいでオーバーフローし、panic するのを避けるため、 16 | /// 同等の処理を `map` 中に再度書いている。 17 | /// 18 | /// Pell 方程式を解く際、解は [`i128`](https://doc.rust-lang.org/std/primitive.i128.html) 19 | /// に収まるが上記の問題で panic したのでこうなった。 20 | /// 実際には release build では問題なく動くことが予想されるので無視してもいい気もするが... 21 | /// 22 | /// # Examples 23 | /// ``` 24 | /// use nekolib::math::continued_fraction; 25 | /// 26 | /// let frac_exp = [1, 2]; 27 | /// let sqrt3 = std::iter::once(1).chain(frac_exp.iter().copied().cycle()); 28 | /// let mut it = continued_fraction(sqrt3); 29 | /// assert_eq!(it.next(), Some((1, 1))); 30 | /// assert_eq!(it.next(), Some((2, 1))); 31 | /// assert_eq!(it.next(), Some((5, 3))); 32 | /// assert_eq!(it.next(), Some((7, 4))); 33 | /// assert_eq!(it.next(), Some((19, 11))); 34 | /// assert_eq!(it.next(), Some((26, 15))); 35 | /// 36 | /// let (x, y) = it.nth(24).unwrap(); 37 | /// assert!(((x as f64 / y as f64) - 3.0_f64.sqrt()).abs() < 1.0e-16); 38 | /// ``` 39 | pub fn continued_fraction( 40 | mut a: impl Iterator, 41 | ) -> impl Iterator { 42 | let a0 = a.next().unwrap(); 43 | let frac = std::iter::successors( 44 | Some(((1, a0), (0, 1), a.next().unwrap())), 45 | move |&((nx, ny), (dx, dy), ai)| { 46 | Some(((ny, nx + ai * ny), (dy, dx + ai * dy), a.next().unwrap())) 47 | }, 48 | ) 49 | .map(|((nx, ny), (dx, dy), ai)| (nx + ai * ny, dx + ai * dy)); 50 | std::iter::once((a0, 1)).chain(frac) 51 | } 52 | -------------------------------------------------------------------------------- /crates/math/convolution/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "convolution" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | modint = { path = "../modint" } 10 | garner = { path = "../garner" } 11 | -------------------------------------------------------------------------------- /crates/math/count_prime/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "count_prime" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/math/crt/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "crt" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | gcd_recip = { path = "../gcd_recip" } 11 | -------------------------------------------------------------------------------- /crates/math/digit_sum/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "digit_sum" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/math/digit_sum/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 桁和。 2 | 3 | /// 桁和。 4 | /// 5 | /// # Examples 6 | /// ``` 7 | /// use nekolib::math::DigitSum; 8 | /// 9 | /// assert_eq!(2_u32.pow(15).digit_sum(10), 3 + 2 + 7 + 6 + 8); 10 | /// assert_eq!(123_u32.digit_pow_sum(10, 2), 1*1 + 2*2 + 3*3); 11 | /// assert_eq!(0xACE_u32.digit_sum(16), 0xA + 0xC + 0xE); 12 | /// 13 | /// assert_eq!(12345_u32.digit_pow_sum(10, 0), 5); // the number of digits 14 | /// assert_eq!(0_u32.digit_pow_sum(10, 0), 1); 15 | /// ``` 16 | pub trait DigitSum: Sized { 17 | fn digit_pow_sum(self, base: Self, exp: u32) -> Self; 18 | fn digit_sum(self, base: Self) -> Self { self.digit_pow_sum(base, 1) } 19 | } 20 | 21 | macro_rules! impl_uint { 22 | ($t:ty) => { 23 | impl DigitSum for $t { 24 | fn digit_pow_sum(mut self, base: Self, exp: u32) -> Self { 25 | if self == 0 { 26 | return if exp == 0 { 1 } else { 0 }; 27 | } 28 | let mut res = 0; 29 | while self > 0 { 30 | res += (self % base).pow(exp); 31 | self /= base; 32 | } 33 | res 34 | } 35 | } 36 | }; 37 | ( $($t:ty)* ) => { $(impl_uint!($t);)* }; 38 | } 39 | 40 | impl_uint!(u8 u16 u32 u64 u128 usize); 41 | -------------------------------------------------------------------------------- /crates/math/digits/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "digits" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/math/digits/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub trait Digits: Sized { 2 | fn digits(self, base: Self) -> DigitsIter; 3 | } 4 | 5 | pub struct DigitsIter { 6 | x: I, 7 | base: I, 8 | } 9 | 10 | impl DigitsIter { 11 | pub fn new(x: I, base: I) -> Self { Self { x, base } } 12 | } 13 | 14 | macro_rules! impl_uint { 15 | ( $($ty:ty)* ) => { $( 16 | impl Digits for $ty { 17 | fn digits(self, base: Self) -> DigitsIter { 18 | DigitsIter::new(self, base) 19 | } 20 | } 21 | impl Iterator for DigitsIter<$ty> { 22 | type Item = $ty; 23 | fn next(&mut self) -> Option<$ty> { 24 | if self.x == 0 { 25 | return None; 26 | } 27 | 28 | let res = self.x % self.base; 29 | self.x /= self.base; 30 | Some(res) 31 | } 32 | } 33 | )* } 34 | } 35 | 36 | impl_uint! { u8 u16 u32 u64 u128 usize } 37 | 38 | #[test] 39 | fn sanity_check() { 40 | let a: Vec<_> = 1234_u32.digits(10).collect(); 41 | assert_eq!(a, [4, 3, 2, 1]); 42 | 43 | let a: Vec<_> = 0_u32.digits(10).collect(); 44 | assert!(a.is_empty()); 45 | 46 | let a: Vec<_> = 13_u32.digits(2).collect(); 47 | assert_eq!(a, [1, 0, 1, 1]); 48 | } 49 | -------------------------------------------------------------------------------- /crates/math/divisors/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "divisors" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/math/dlog/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dlog" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | gcd = { path = "../gcd" } 11 | mod_pow = { path = "../mod_pow" } 12 | carmichael_lambda = { path = "../carmichael_lambda" } 13 | factors = { path = "../factors" } 14 | divisors = { path = "../divisors" } 15 | -------------------------------------------------------------------------------- /crates/math/equiv_mod/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "equiv_mod" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | gcd_recip = { path = "../gcd_recip" } 10 | -------------------------------------------------------------------------------- /crates/math/euler_phi/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "euler_phi" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | factors = { path = "../factors" } 11 | 12 | [dev-dependencies] 13 | gcd = { path = "../gcd" } 14 | -------------------------------------------------------------------------------- /crates/math/euler_phi/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Euler の $\\varphi$ 関数。 2 | 3 | use factors::Factors; 4 | 5 | /// Euler の $\\varphi$ 関数。 6 | /// 7 | /// $n$ 以下の自然数のうち、$n$ と互いに素であるものの個数を返す。$1$ 8 | /// と $1$ は互いに素であることに注意。 9 | /// 10 | /// # Note 11 | /// 素数冪 $p^k$, $p\'^{k\'}$ ($p\\ne p\'$) について 12 | /// $\\varphi(p^k p\'^{k\'}) = \\varphi(p^k)\\varphi(p\'^{k\'})$ 13 | /// が成り立つ。また、$\\varphi(p^k) = \\varphi^{k-1}\\cdot(p-1)$ が成り立つ。 14 | /// 15 | /// # Complexity 16 | /// $O(\\sqrt{n})$ time. 17 | /// 18 | /// # Examples 19 | /// ``` 20 | /// use nekolib::math::EulerPhi; 21 | /// 22 | /// assert_eq!(1_u64.euler_phi(), 1); 23 | /// assert_eq!(60_u64.euler_phi(), 16); 24 | /// ``` 25 | pub trait EulerPhi { 26 | fn euler_phi(self) -> Self; 27 | } 28 | 29 | macro_rules! impl_uint { 30 | ($t:ty) => { 31 | impl EulerPhi for $t { 32 | fn euler_phi(self) -> Self { 33 | self.factors().map(|(p, e)| p.pow(e - 1) * (p - 1)).product() 34 | } 35 | } 36 | }; 37 | ( $($t:ty)* ) => { $(impl_uint!($t);)* }; 38 | } 39 | 40 | impl_uint!(u8 u16 u32 u64 u128 usize); 41 | 42 | #[test] 43 | fn test_naive() { 44 | use gcd::Gcd; 45 | let n = 100_usize; 46 | for i in 1..=n { 47 | let phi = (1..=i).filter(|&j| i.gcd(j) == 1).count(); 48 | assert_eq!(i.euler_phi(), phi); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /crates/math/factors/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "factors" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/math/factors_dup/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "factors_dup" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/math/frac_approx/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "frac_approx" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/math/fraction_bisect/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fraction_bisect" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/math/garner/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "garner" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | gcd_recip = { path = "../gcd_recip" } 10 | -------------------------------------------------------------------------------- /crates/math/garner/test.py: -------------------------------------------------------------------------------- 1 | a64 = (2**64 - 1) ** 2 * 2**25 2 | a128 = (2**128 - 1) ** 2 * 2**24 3 | 4 | m64 = [ 5 | 33 << 25 | 1, 6 | 51 << 25 | 1, 7 | 63 << 25 | 1, 8 | 7 << 26 | 1, 9 | 27 << 26 | 1, 10 | 15 << 27 | 1, 11 | ] 12 | m128 = [ 13 | 45 << 24 | 1, 14 | 73 << 24 | 1, 15 | 127 << 24 | 1, 16 | 5 << 25 | 1, 17 | 33 << 25 | 1, 18 | 51 << 25 | 1, 19 | 63 << 25 | 1, 20 | 7 << 26 | 1, 21 | 27 << 26 | 1, 22 | 15 << 27 | 1, 23 | ] 24 | 25 | rm64 = [*map(lambda mi: (a64 % mi, mi), m64)] 26 | rm128 = [*map(lambda mi: (a128 % mi, mi), m128)] 27 | print(rm64) 28 | print(rm128) 29 | 30 | print(a64 % 998244353) 31 | print(a128 % 998244353) 32 | -------------------------------------------------------------------------------- /crates/math/gcd/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gcd" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/math/gcd/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 最大公約数。 2 | 3 | /// 最大公約数。 4 | /// 5 | /// # Complexity 6 | /// $O(\\log(\\min\\{m, n\\}))$ time. 7 | /// 8 | /// # Examples 9 | /// ``` 10 | /// use nekolib::math::Gcd; 11 | /// 12 | /// assert_eq!(12_u32.gcd(18), 6); 13 | /// assert_eq!(13_i32.gcd(-3), 1); 14 | /// assert_eq!(60_u32.gcd(90).gcd(150), 30); 15 | /// 16 | /// assert_eq!(0_u32.gcd(0), 0); 17 | /// assert_eq!(0_u32.gcd(1), 1); 18 | /// ``` 19 | pub trait Gcd { 20 | fn gcd(self, other: Self) -> Self; 21 | } 22 | 23 | macro_rules! impl_uint { 24 | ($t:ty) => { 25 | impl Gcd for $t { 26 | fn gcd(mut self, mut other: Self) -> Self { 27 | while other > 0 { 28 | let tmp = self % other; 29 | self = std::mem::replace(&mut other, tmp); 30 | } 31 | self 32 | } 33 | } 34 | }; 35 | ( $($t:ty)* ) => { $(impl_uint!($t);)* }; 36 | } 37 | 38 | macro_rules! impl_int { 39 | ($t:ty) => { 40 | impl Gcd for $t { 41 | fn gcd(mut self, mut other: Self) -> Self { 42 | while other != 0 { 43 | let tmp = self.rem_euclid(other); 44 | self = std::mem::replace(&mut other, tmp); 45 | } 46 | self.abs() 47 | } 48 | } 49 | }; 50 | ( $($t:ty)* ) => { $(impl_int!($t);)* }; 51 | } 52 | 53 | impl_uint!(u8 u16 u32 u64 u128 usize); 54 | impl_int!(i8 i16 i32 i64 i128 isize); 55 | -------------------------------------------------------------------------------- /crates/math/gcd_recip/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gcd_recip" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/math/harmonic_floor_sum/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "harmonic_floor_sum" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/math/interpolation/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "interpolation" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | gcd_recip = { path = "../gcd_recip" } 10 | const_div = { path = "../const_div" } 11 | -------------------------------------------------------------------------------- /crates/math/is_close_float/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "is_close_float" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/math/lcm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lcm" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | gcd = { path = "../gcd" } 10 | -------------------------------------------------------------------------------- /crates/math/lcm/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 最小公倍数。 2 | 3 | /// 最小公倍数。 4 | /// 5 | /// # Complexity 6 | /// $O(\\log(\\min\\{m, n\\}))$ time. 7 | /// 8 | /// # Examples 9 | /// ``` 10 | /// use nekolib::math::Lcm; 11 | /// 12 | /// assert_eq!(12_u32.lcm(18), 36); 13 | /// assert_eq!(13_i32.lcm(-3), -39); 14 | /// assert_eq!(60_u32.lcm(90).lcm(150), 900); 15 | /// 16 | /// assert_eq!(0_u32.lcm(0), 0); 17 | /// assert_eq!(0_u32.lcm(1), 0); 18 | /// ``` 19 | pub trait Lcm { 20 | fn lcm(self, other: Self) -> Self; 21 | } 22 | 23 | use gcd::Gcd; 24 | 25 | macro_rules! impl_int { 26 | ($t:ty) => { 27 | impl Lcm for $t { 28 | fn lcm(self, other: Self) -> Self { 29 | if self == 0 || other == 0 { 30 | 0 31 | } else { 32 | self / self.gcd(other) * other 33 | } 34 | } 35 | } 36 | }; 37 | ( $($t:ty)* ) => { $(impl_int!($t);)* }; 38 | } 39 | 40 | impl_int!(u8 u16 u32 u64 u128 usize); 41 | impl_int!(i8 i16 i32 i64 i128 isize); 42 | -------------------------------------------------------------------------------- /crates/math/linear_floor_sum/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "linear_floor_sum" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | -------------------------------------------------------------------------------- /crates/math/linear_sieve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "linear_sieve" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | gcd_recip = { path = "../gcd_recip" } 11 | -------------------------------------------------------------------------------- /crates/math/miller_rabin/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "miller_rabin" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/math/mod_ackermann/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mod_ackermann" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | mod_pow = { path = "../mod_pow" } 11 | mod_tetration = { path = "../mod_tetration" } 12 | -------------------------------------------------------------------------------- /crates/math/mod_factorial_binom/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mod_factorial_binom" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | mod_recip_table_ = { path = "../mod_recip_table_" } 10 | -------------------------------------------------------------------------------- /crates/math/mod_ord/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mod_ord" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | mod_pow = { path = "../mod_pow" } 11 | carmichael_lambda = { path = "../carmichael_lambda" } 12 | factors_dup = { path = "../factors_dup" } 13 | gcd = { path = "../gcd" } 14 | -------------------------------------------------------------------------------- /crates/math/mod_pow/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mod_pow" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/math/mod_pow/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 冪乗。 2 | 3 | /// 冪乗。 4 | /// 5 | /// $a^b \\bmod n$ を返す。 6 | /// 7 | /// # Complexity 8 | /// $O(\\log(b))$ time. 9 | /// 10 | /// # Examples 11 | /// ``` 12 | /// use nekolib::math::ModPow; 13 | /// 14 | /// assert_eq!(3_u64.mod_pow(14, 10), 9); 15 | /// assert_eq!(2_u64.mod_pow(11, 1024), 0); 16 | /// assert_eq!(0_u64.mod_pow(0, 1), 0); 17 | /// ``` 18 | pub trait ModPow { 19 | fn mod_pow(self, b: Self, n: Self) -> Self; 20 | } 21 | 22 | macro_rules! impl_uint { 23 | ($t:ty) => { 24 | impl ModPow for $t { 25 | fn mod_pow(self, mut b: Self, n: Self) -> Self { 26 | if n == 1 { 27 | return 0; // in case 0^0 28 | } 29 | let mut res = 1; 30 | let mut a = self % n; 31 | while b > 0 { 32 | if b & 1 == 1 { 33 | res = res * a % n; 34 | } 35 | a = a * a % n; 36 | b >>= 1; 37 | } 38 | res 39 | } 40 | } 41 | }; 42 | ( $($t:ty)* ) => { $(impl_uint!($t);)* }; 43 | } 44 | 45 | impl_uint!(u8 u16 u32 u64 u128 usize); 46 | 47 | #[test] 48 | fn test() { 49 | for n in 1_u64..=30 { 50 | for a in 0..30 { 51 | let mut expected = 1 % n; 52 | for b in 0..30 { 53 | assert_eq!(a.mod_pow(b, n), expected); 54 | expected = expected * a % n; 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /crates/math/mod_recip_table_/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mod_recip_table_" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | 10 | [dev-dependencies] 11 | factors_dup = { path = "../factors_dup" } 12 | gcd = { path = "../gcd" } 13 | -------------------------------------------------------------------------------- /crates/math/mod_tetration/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mod_tetration" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | euler_phi = { path = "../euler_phi" } 11 | -------------------------------------------------------------------------------- /crates/math/modint/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "modint" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | # assoc_val = { path = "../../traits/assoc_val" } 11 | # additive = { path = "../../traits/additive" } 12 | # multiplicative = { path = "../../traits/multiplicative" } 13 | gcd_recip = { path = "../gcd_recip" } 14 | # mod_pow = { path = "../mod_pow" } 15 | -------------------------------------------------------------------------------- /crates/math/polynomial/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "polynomial" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | modint = { path = "../modint" } 11 | convolution = { path = "../convolution" } 12 | -------------------------------------------------------------------------------- /crates/math/prime_pi_/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "prime_pi_" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | bisect = { path = "../../traits/bisect" } 10 | linear_sieve = { path = "../linear_sieve" } 11 | -------------------------------------------------------------------------------- /crates/math/segmented_factor_sieve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "segmented_factor_sieve" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | sqrt = { path = "../sqrt" } 10 | -------------------------------------------------------------------------------- /crates/math/sieve_n2_plus_1/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sieve_n2_plus_1" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | 10 | [dev-dependencies] 11 | linear_sieve = { path = "../linear_sieve" } 12 | -------------------------------------------------------------------------------- /crates/math/sieve_n2_plus_n_plus_1/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sieve_n2_plus_n_plus_1" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | 10 | [dev-dependencies] 11 | linear_sieve = { path = "../linear_sieve" } 12 | -------------------------------------------------------------------------------- /crates/math/slope_function/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "slope_function" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/math/sqrt/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sqrt" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/math/sqrt_fraction_/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sqrt_fraction_" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | sqrt = { path = "../sqrt" } 10 | -------------------------------------------------------------------------------- /crates/math/stern_brocot_/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "stern_brocot_" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/math/stern_brocot_/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Stern--Brocot tree 2 | 3 | /// Stern--Brocot tree 4 | /// 5 | /// $a/b = 0/1=0$ と $c/d = 1/0=\\infty$ で初期化し、その mediant 6 | /// $x/y = (a+b)/(c+d)$ 7 | /// を探索する。 8 | /// 9 | /// $x/y$ が所望の条件 `ok` を満たすならそれを [`Ok`] として返す。 10 | /// 条件 `large` を満たすなら $c/d\\gets x/y$、そうでなければ $a/b\\gets x/y$ 11 | /// として探索を進める。 12 | /// 分母が $n$ を超えても `ok` を満たさなければ、$((a, b), (c, d))$ を 13 | /// [`Err`] として返す。 14 | /// 15 | /// [`Ok`]: https://doc.rust-lang.org/nightly/std/result/enum.Result.html#variant.Ok 16 | /// [`Err`]: https://doc.rust-lang.org/nightly/std/result/enum.Result.html#variant.Err 17 | /// 18 | /// # Examples 19 | /// ``` 20 | /// use nekolib::math::stern_brocot; 21 | /// 22 | /// let (num, den) = 23 | /// stern_brocot(10_i128.pow(18), |n, d| n * n > 3 * d * d, |_, _| false) 24 | /// .err().unwrap().0; 25 | /// 26 | /// let sqrt3 = num as f64 / den as f64; 27 | /// assert!((sqrt3 - 3.0_f64.sqrt()).abs() < 1.0e-16); 28 | /// assert_eq!((num, den), (734231055024833855, 423908497265970753)); 29 | /// ``` 30 | pub fn stern_brocot( 31 | n: i128, 32 | mut large: impl FnMut(i128, i128) -> bool, 33 | mut ok: impl FnMut(i128, i128) -> bool, 34 | ) -> Result<(i128, i128), ((i128, i128), (i128, i128))> { 35 | let (mut a, mut b) = (0, 1); 36 | let (mut c, mut d) = (1, 0); 37 | loop { 38 | let x = a + c; 39 | let y = b + d; 40 | if y > n { 41 | return Err(((a, b), (c, d))); 42 | } 43 | if ok(x, y) { 44 | return Ok((x, y)); 45 | } 46 | if large(x, y) { 47 | c = x; 48 | d = y; 49 | } else { 50 | a = x; 51 | b = y; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /crates/math/two_sat/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "two_sat" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | scc_ = { path = "../../graph/scc_" } 11 | -------------------------------------------------------------------------------- /crates/seq/kmp/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "kmp" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | push_pop = { path = "../../traits/push_pop" } 11 | # pat_searcher = { path = "../../traits/pat_searcher" } 12 | -------------------------------------------------------------------------------- /crates/seq/kmp/src/main.rs: -------------------------------------------------------------------------------- 1 | use kmp::KmpSearcher; 2 | use push_pop::PushBack; 3 | 4 | fn main() { 5 | // let kmp: KmpSearcher<_> = "aabaabaaa".into(); 6 | let kmp: KmpSearcher<_> = vec![0, 0, 1, 0, 0, 1, 0, 0, 0].into(); 7 | eprintln!("{:?}", kmp); 8 | 9 | let mut kmp: KmpSearcher<_> = vec![].into(); 10 | for &x in &[0, 0, 1, 0, 0, 1, 0, 0, 0] { 11 | kmp.push_back(x); 12 | // eprintln!("{:#?}", kmp); 13 | } 14 | 15 | let kmp = kmp; 16 | let text = [2, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0]; 17 | for r in kmp.occurrences(&text) { 18 | eprintln!("{:?}", r); 19 | } 20 | 21 | // let kmp: KmpSearcher = vec![].into(); 22 | let kmp = KmpSearcher::::from(vec![]); 23 | for r in kmp.occurrences(&text) { 24 | eprintln!("{:?}", r); 25 | } 26 | 27 | let kmp = KmpSearcher::::from(vec![0, 0, 1, 0, 0, 1, 0, 0, 0]); 28 | eprintln!("{:?}", kmp); 29 | for r in kmp.occurrences(&text) { 30 | eprintln!("{:?}", r); 31 | } 32 | let o: Vec<_> = kmp.occurrences(&text).collect(); 33 | eprintln!("{:?}", o); 34 | 35 | eprintln!( 36 | "{:?}", 37 | KmpSearcher::from(vec![0, 0, 1, 0, 2, 0, 0, 1, 0, 2]) 38 | ); 39 | 40 | eprintln!("{:?}", KmpSearcher::from(vec![0; 5])); 41 | 42 | // s[1] = "b"; s[2] = "a"; s[n] = s[n-1] s[n-2] 43 | // b a ab aba abaab abaababa abaababaabaab 44 | let buf = vec![0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1]; 45 | let mut k_dyn: KmpSearcher = vec![].into(); 46 | for i in 0..buf.len() { 47 | k_dyn.push_back(buf[i]); 48 | let k: KmpSearcher<_> = buf[..=i].to_vec().into(); 49 | assert_eq!(k, k_dyn); 50 | } 51 | 52 | eprintln!("{:?}", k_dyn); 53 | } 54 | -------------------------------------------------------------------------------- /crates/seq/suffix_array/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "suffix_array" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/seq/suffix_array/src/main.rs: -------------------------------------------------------------------------------- 1 | use suffix_array::SuffixArray; 2 | 3 | fn main() { 4 | let text = "abracadabra".to_string(); 5 | let sa: Vec<_> = SuffixArray::from(text).into(); 6 | assert_eq!(sa, [11, 10, 7, 0, 3, 5, 8, 1, 4, 6, 9, 2]); 7 | 8 | let text = "mississippi".to_string(); 9 | let sa = SuffixArray::from(text.clone()); 10 | 11 | for i in sa.search(&"is".chars().collect::>()) { 12 | eprintln!("{:?}", &text[i..]); 13 | } 14 | 15 | for i in sa.search(&"i".chars().collect::>()) { 16 | eprintln!("{:?}", &text[i..]); 17 | } 18 | 19 | let sa: Vec<_> = sa.into(); 20 | assert_eq!(sa, [11, 10, 7, 4, 1, 0, 9, 8, 6, 3, 5, 2]); 21 | 22 | let text = "aabaaa".to_string(); 23 | let sa = SuffixArray::from(text.clone()); 24 | for pat in &["a", "aa", "b", "ba", "bb", "xyz"] { 25 | eprintln!( 26 | "{:?}", 27 | sa.search(&pat.chars().collect::>()) 28 | .map(|i| &text[i..]) 29 | .collect::>() 30 | ); 31 | } 32 | 33 | let sa: Vec<_> = SuffixArray::from("abababab".to_string()).into(); 34 | assert_eq!(sa, [8, 6, 4, 2, 0, 7, 5, 3, 1]); 35 | 36 | let text = "abracadabra".to_string(); 37 | let sa = SuffixArray::from(text.chars().collect::>()); 38 | eprintln!("{:?}", sa); 39 | } 40 | -------------------------------------------------------------------------------- /crates/seq/z_algo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "z_algo" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | # pat_searcher = { path = "../../traits/pat_searcher" } 11 | -------------------------------------------------------------------------------- /crates/traits/act/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "act" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | binop = { path = "../binop" } 11 | action = { path = "../action" } 12 | -------------------------------------------------------------------------------- /crates/traits/act/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 区間作用に関するトレイトです。 2 | 3 | use std::ops::RangeBounds; 4 | 5 | use action::MonoidAction; 6 | use binop::Magma; 7 | 8 | /// 区間作用を行う。 9 | pub trait Act> { 10 | /// `r` で指定される区間に作用を行う。 11 | type Action: MonoidAction; 12 | fn act( 13 | &mut self, 14 | r: R, 15 | x: <::Operator as Magma>::Set, 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /crates/traits/action/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "action" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | binop = { path = "../binop" } 11 | -------------------------------------------------------------------------------- /crates/traits/action/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 作用モノイド。 2 | 3 | use binop::{Magma, Monoid}; 4 | 5 | /// 作用モノイド。 6 | pub trait MonoidAction { 7 | /// 作用を行う型。 8 | type Operator: Monoid; 9 | /// 作用される型。 10 | type Operand: Monoid; 11 | 12 | fn operator(&self) -> &Self::Operator; 13 | fn operand(&self) -> &Self::Operand; 14 | /// 作用を行う。 15 | fn act( 16 | &self, 17 | x: ::Set, 18 | op: ::Set, 19 | ) -> ::Set; 20 | } 21 | -------------------------------------------------------------------------------- /crates/traits/additive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "additive" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/traits/additive/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 加法に関するトレイトたちです。 2 | //! 3 | //! これを実装したクラスは `OpAdd` によって和を求められます。 4 | //! 区間和を求めるデータ構造などに使います。 5 | 6 | use std::ops::Add; 7 | 8 | /// 加法の単位元 $0$ を定義する。 9 | pub trait Zero: Add + Sized { 10 | /// 加法の単位元 $0$ を返す。 11 | fn zero() -> Self; 12 | } 13 | /// 加法が結合法則を満たすことを示す。 14 | /// 15 | /// $$ x, y, z \\in S \\implies (x + y) + z = x + (y + z). $$ 16 | pub trait AddAssoc: Add + Sized {} 17 | /// 加法が交換法則を満たすことを示す。 18 | /// 19 | /// $$ x, y \\in S \\implies x + y = y + x. $$ 20 | pub trait AddComm: Add + Sized {} 21 | 22 | macro_rules! impl_trait { 23 | ( 24 | $( impl ($T:ty) for { $( $U:ty ),* } $S:tt )* 25 | ) => { 26 | $( $( impl $T for $U $S )* )* 27 | }; 28 | } 29 | 30 | impl_trait! { 31 | impl (Zero) for {i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize} { 32 | fn zero() -> Self { 0 } 33 | } 34 | impl (AddAssoc) for {i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize} {} 35 | impl (AddComm) for {i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize} {} 36 | } 37 | -------------------------------------------------------------------------------- /crates/traits/binop/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "binop" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/traits/bisect/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bisect" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/traits/count/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "count" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/traits/count/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 計数クエリ。 2 | 3 | use std::fmt::Debug; 4 | use std::ops::RangeBounds; 5 | 6 | /// 計数クエリ。 7 | pub trait Count { 8 | fn count(&self, range: impl RangeBounds, value: I) -> usize; 9 | } 10 | 11 | /// 三方向計数クエリ。 12 | pub trait Count3way { 13 | fn count_3way( 14 | &self, 15 | range: impl RangeBounds, 16 | value: I, 17 | ) -> Count3wayResult; 18 | } 19 | 20 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 21 | pub struct Count3wayResult { 22 | lt: usize, 23 | eq: usize, 24 | gt: usize, 25 | } 26 | 27 | impl Count3wayResult { 28 | pub fn new(lt: usize, eq: usize, gt: usize) -> Self { Self { lt, eq, gt } } 29 | pub fn lt(&self) -> usize { self.lt } 30 | pub fn eq(&self) -> usize { self.eq } 31 | pub fn gt(&self) -> usize { self.gt } 32 | pub fn le(&self) -> usize { self.lt + self.eq } 33 | pub fn ge(&self) -> usize { self.gt + self.eq } 34 | pub fn ne(&self) -> usize { self.lt + self.gt } 35 | } 36 | -------------------------------------------------------------------------------- /crates/traits/disjoint-set/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "disjoint-set" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/traits/disjoint-set/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 素集合に関するトレイトです。 2 | 3 | /// 共通要素を持たない集合族で、併合が可能なもの。 4 | pub trait DisjointSet { 5 | /// 集合族を $\\{\\{0\\}, \\{1\\}, \\dots, \\{n-1\\}\\}$ で初期化する。 6 | fn new(n: usize) -> Self; 7 | /// 集合族全体に含まれる要素数 $n$ を返す。 8 | fn len(&self) -> usize; 9 | /// 集合族が空であれば `true` を返す。 10 | fn is_empty(&self) -> bool { self.len() == 0 } 11 | /// $u$ を含む集合と $v$ を含む集合を併合する。 12 | /// 集合族に変化があれば `true` を返す。 13 | /// $u$ と $v$ が元々同じ集合に含まれていれば `false` を返す。 14 | fn unite(&mut self, u: usize, v: usize) -> bool; 15 | /// $u$ を含む集合の代表元を返す。 16 | fn repr(&self, u: usize) -> usize; 17 | /// $u$ を含む集合の要素数を返す。 18 | fn count(&self, u: usize) -> usize; 19 | /// $u$ と $v$ が同じ集合に含まれていれば `true` を返す。 20 | fn equiv(&self, u: usize, v: usize) -> bool { self.repr(u) == self.repr(v) } 21 | /// $u$ を含む集合の要素を列挙する。 22 | fn subset(&self, u: usize) -> Vec { 23 | (0..self.len()).filter(|&v| self.equiv(u, v)).collect() 24 | } 25 | /// 分割を返す。 26 | /// 27 | /// $u$ が代表元のとき、$u$ 番目の `Vec` にそれと等価な要素たちが入る。 28 | fn partition(&self) -> Vec> { 29 | let mut res = vec![vec![]; self.len()]; 30 | for i in 0..self.len() { 31 | res[self.repr(i)].push(i); 32 | } 33 | res 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /crates/traits/elastic_slice/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "elastic_slice" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/traits/elastic_slice/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub trait ExpandFront { 2 | fn expand_front(&mut self); 3 | } 4 | 5 | pub trait ExpandBack { 6 | fn expand_back(&mut self); 7 | } 8 | 9 | pub trait ShrinkFront { 10 | fn shrink_front(&mut self); 11 | } 12 | 13 | pub trait ShrinkBack { 14 | fn shrink_back(&mut self); 15 | } 16 | 17 | pub trait ElasticSlice { 18 | fn reset(&mut self); 19 | fn full_len(&self) -> usize; 20 | fn start(&self) -> usize; 21 | fn end(&self) -> usize; 22 | fn len(&self) -> usize { self.end() - self.start() } 23 | fn is_empty(&self) -> bool { self.start() == self.end() } 24 | } 25 | 26 | pub trait SliceHash { 27 | type Salt; 28 | type Hashed; 29 | fn hash(&self, x: Self::Salt) -> Self::Hashed; 30 | } 31 | -------------------------------------------------------------------------------- /crates/traits/find_nth/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "find_nth" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/traits/find_nth/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! $n$ 番目の出現位置クエリ。 2 | 3 | use std::ops::RangeBounds; 4 | 5 | /// $n$ 番目の出現位置クエリ。 6 | pub trait FindNth { 7 | fn find_nth( 8 | &self, 9 | range: impl RangeBounds, 10 | value: I, 11 | n: usize, 12 | ) -> Option; 13 | } 14 | -------------------------------------------------------------------------------- /crates/traits/fold/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fold" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | binop = { path = "../binop" } 11 | -------------------------------------------------------------------------------- /crates/traits/fold/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 区間和に関するトレイトです。 2 | 3 | use std::ops::RangeBounds; 4 | 5 | use binop::{Magma, Monoid}; 6 | 7 | /// 区間和を求める。 8 | pub trait Fold> { 9 | type Output: Monoid; 10 | /// `r` で指定される区間の和を返す。 11 | fn fold(&self, r: R) -> ::Set; 12 | } 13 | -------------------------------------------------------------------------------- /crates/traits/fold_bisect/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fold_bisect" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | binop = { path = "../binop" } 11 | fold = { path = "../fold" } 12 | -------------------------------------------------------------------------------- /crates/traits/get_mut/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "get_mut" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/traits/get_mut/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::ops::{Deref, DerefMut}; 2 | 3 | pub trait GetMut<'a> { 4 | type Output: Deref + DerefMut; 5 | fn get_mut(&'a mut self, i: usize) -> Option; 6 | } 7 | -------------------------------------------------------------------------------- /crates/traits/group_by/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "group_by" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/traits/group_by/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! イテレータのグルーピング。 2 | 3 | use std::collections::BTreeMap; 4 | 5 | /// イテレータのグルーピング。 6 | /// 7 | /// # Suggestions 8 | /// `BTreeMap` と `HashMap` 用で分けるべき? メソッド名を冗長にしたくない。 9 | /// 10 | /// # See also 11 | /// [`UsizeGroupBy`] 12 | /// 13 | /// [`UsizeGroupBy`]: trait.UsizeGroupBy.html 14 | pub trait GroupBy { 15 | /// # Examples 16 | /// ``` 17 | /// use nekolib::traits::GroupBy; 18 | /// 19 | /// let a = vec![1, 4, 3, -5, -6, 0, 2, -2, 3]; 20 | /// let g1 = a.iter().copied().group_by(|&ai: &i32| ai.rem_euclid(3)); 21 | /// let g2 = a.iter().copied().group_by(|&ai: &i32| ai % 3); 22 | /// 23 | /// assert_eq!(g1.len(), 3); 24 | /// assert_eq!(g1[&0], [3, -6, 0, 3]); 25 | /// assert_eq!(g1[&1], [1, 4, -5, -2]); 26 | /// assert_eq!(g1[&2], [2]); 27 | /// 28 | /// assert_eq!(g2.len(), 4); 29 | /// assert_eq!(g2[&-2], [-5, -2]); 30 | /// assert_eq!(g2[&0], [3, -6, 0, 3]); 31 | /// assert_eq!(g2[&1], [1, 4]); 32 | /// assert_eq!(g2[&2], [2]); 33 | /// ``` 34 | fn group_by(self, key: impl FnMut(&V) -> K) -> BTreeMap>; 35 | } 36 | 37 | impl> GroupBy for I { 38 | fn group_by( 39 | self, 40 | mut key: impl FnMut(&V) -> K, 41 | ) -> BTreeMap> { 42 | let mut res = BTreeMap::new(); 43 | for v in self { 44 | let k = key(&v); 45 | res.entry(k).or_insert(vec![]).push(v); 46 | } 47 | res 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /crates/traits/max/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "max" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/traits/min/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "min" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/traits/multiplicative/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "multiplicative" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/traits/multiplicative/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 乗法に関するトレイトたちです。 2 | //! 3 | //! これを実装したクラスは `OpMul` によって積を求められます。 4 | //! 区間和を求めるデータ構造などに使います。 5 | 6 | use std::ops::Mul; 7 | 8 | /// 乗法の単位元 $1$ を定義する。 9 | pub trait One: Mul + Sized { 10 | /// 乗法の単位元 $1$ を返す。 11 | fn one() -> Self; 12 | } 13 | /// 乗法の逆元を定義する。 14 | pub trait MulRecip { 15 | /// 返り値の型。 16 | type Output; 17 | /// 乗法における $x$ の逆元 $x^{-1}$ を返す。 18 | fn mul_recip(self) -> Self::Output; 19 | } 20 | /// 乗法が結合法則を満たすことを示す。 21 | /// 22 | /// $$ x, y, z \\in S \\implies (x \\times y) \\times z = x \\times (y \\times z). $$ 23 | pub trait MulAssoc: Mul + Sized {} 24 | /// 乗法が交換法則を満たすことを示す。 25 | /// 26 | /// $$ x, y \\in S \\implies x \\times y = y \\times x. $$ 27 | pub trait MulComm: Mul + Sized {} 28 | 29 | macro_rules! impl_trait { 30 | ( 31 | $( impl ($T:ty) for { $( $U:ty ),* } $S:tt )* 32 | ) => { 33 | $( $( impl $T for $U $S )* )* 34 | }; 35 | } 36 | 37 | impl_trait! { 38 | impl (One) for {i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize} { 39 | fn one() -> Self { 1 } 40 | } 41 | impl (MulAssoc) for {i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize} {} 42 | impl (MulComm) for {i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize} {} 43 | } 44 | -------------------------------------------------------------------------------- /crates/traits/pat_searcher/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pat_searcher" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/traits/pat_searcher/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub trait PatSearcher { 2 | type Item: Clone + Eq; 3 | type Output; 4 | fn with>(pat: P) -> Self; 5 | fn occurrences(&self, text: &[Self::Item]) -> Self::Output; 6 | } 7 | -------------------------------------------------------------------------------- /crates/traits/potential_function/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "potential_function" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | binop = { path = "../binop" } 11 | -------------------------------------------------------------------------------- /crates/traits/potential_function/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! ポテンシャル関数。 2 | 3 | pub use binop::{CommutativeGroup, Magma}; 4 | 5 | /// ポテンシャル関数。 6 | pub trait PotentialFunction { 7 | /// 要素の型。 8 | type Item: CommutativeGroup; 9 | 10 | /// 要素数 $n$ の集合 $\\{0, 1, \\dots, n-1\\}$ で初期化する。 11 | fn new(n: usize, cgroup: Self::Item) -> Self; 12 | /// 集合の要素数 $n$ を返す。 13 | fn len(&self) -> usize; 14 | /// 集合が空であれば `true` を返す。 15 | fn is_empty(&self) -> bool { self.len() == 0 } 16 | 17 | /// ポテンシャルの差を定義する。 18 | /// 19 | /// $\\phi(x\_u)-\\phi(x\_v) = w$ とする。 20 | /// 21 | /// 呼び出し前の定義と矛盾しない場合、呼び出し前に $\\phi(x\_u)-\\phi(x\_v)$ が未定義なら 22 | /// `Ok(true)` を、そうでなければ `Ok(false)` を返す。 23 | /// 矛盾する場合、定義は変化せずに `Err(e)` を返す。ただし、`e` 24 | /// は呼び出し前の $\\phi(x\_u) - \\phi(x\_v)$ を表す。 25 | fn relate( 26 | &mut self, 27 | u: usize, 28 | v: usize, 29 | w: ::Set, 30 | ) -> Result::Set>; 31 | 32 | /// ポテンシャルの差を求める。 33 | /// 34 | /// $\\phi(x\_u)-\\phi(x\_v) = w$ であれば `Some(w)` を返す。 35 | /// 未定義ならば `None` を返す。 36 | fn diff(&self, u: usize, v: usize) -> Option<::Set>; 37 | 38 | /// 代表元とのポテンシャルの差を求める。 39 | fn repr_diff(&self, u: usize) -> (usize, ::Set); 40 | } 41 | -------------------------------------------------------------------------------- /crates/traits/push_pop/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "push_pop" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/traits/push_pop/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub trait Push { 2 | type Input; 3 | fn push(&mut self, x: Self::Input); 4 | } 5 | 6 | pub trait PushFront { 7 | type Input; 8 | fn push_front(&mut self, x: Self::Input); 9 | } 10 | 11 | pub trait PushBack { 12 | type Input; 13 | fn push_back(&mut self, x: Self::Input); 14 | } 15 | 16 | pub trait Pop { 17 | type Output; 18 | fn pop(&mut self) -> Option; 19 | } 20 | 21 | pub trait PopFront { 22 | type Output; 23 | fn pop_front(&mut self) -> Option; 24 | } 25 | 26 | pub trait PopBack { 27 | type Output; 28 | fn pop_back(&mut self) -> Option; 29 | } 30 | -------------------------------------------------------------------------------- /crates/traits/quantile/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "quantile" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/traits/quantile/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! $n$ 番目の最小値クエリ。 2 | 3 | use std::ops::RangeBounds; 4 | 5 | /// $n$ 番目の最小値クエリ。 6 | pub trait Quantile { 7 | type Output; 8 | fn quantile( 9 | &self, 10 | range: impl RangeBounds, 11 | n: usize, 12 | ) -> Option; 13 | } 14 | -------------------------------------------------------------------------------- /crates/traits/range_bounds/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "range_bounds" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/traits/range_bounds/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 区間に関するトレイトです。 2 | 3 | use std::ops::{ 4 | Range, RangeBounds, RangeFrom, RangeFull, RangeInclusive, RangeTo, 5 | RangeToInclusive, 6 | }; 7 | 8 | /// 左側が有界である区間。 9 | pub trait StartBounded: RangeBounds {} 10 | /// 左側が閉である区間。 11 | pub trait StartInclusive: StartBounded {} 12 | /// 左側が非有界である区間。 13 | pub trait StartUnbounded: RangeBounds {} 14 | /// 右側が有界である区間。 15 | pub trait EndBounded: RangeBounds {} 16 | /// 右側が開である区間。 17 | pub trait EndExclusive: EndBounded {} 18 | /// 右側が閉である区間。 19 | pub trait EndInclusive: EndBounded {} 20 | /// 右側が非有界である区間。 21 | pub trait EndUnbounded: RangeBounds {} 22 | 23 | impl StartBounded for Range {} 24 | impl StartBounded for RangeInclusive {} 25 | impl StartBounded for RangeFrom {} 26 | impl StartUnbounded for RangeTo {} 27 | impl StartUnbounded for RangeToInclusive {} 28 | impl StartUnbounded for RangeFull {} 29 | 30 | impl StartInclusive for Range {} 31 | impl StartInclusive for RangeInclusive {} 32 | impl StartInclusive for RangeFrom {} 33 | 34 | impl EndBounded for Range {} 35 | impl EndBounded for RangeInclusive {} 36 | impl EndUnbounded for RangeFrom {} 37 | impl EndBounded for RangeTo {} 38 | impl EndBounded for RangeToInclusive {} 39 | impl EndUnbounded for RangeFull {} 40 | 41 | impl EndExclusive for Range {} 42 | impl EndInclusive for RangeInclusive {} 43 | impl EndExclusive for RangeTo {} 44 | impl EndInclusive for RangeToInclusive {} 45 | -------------------------------------------------------------------------------- /crates/traits/set_value/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "set_value" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/traits/set_value/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 値の代入に関するトレイトです。 2 | 3 | /// 値の代入ができることを示す。 4 | /// 5 | /// 典型的には、`I` が `usize` であれば特定の要素に対する代入を指し、 6 | /// `Range` であれば区間に対する代入を指す。 7 | pub trait SetValue { 8 | /// 代入される型。 9 | type Input; 10 | /// `i` で指定される要素に `x` を代入する。 11 | fn set_value(&mut self, i: I, x: Self::Input); 12 | } 13 | -------------------------------------------------------------------------------- /crates/traits/stateful_predicate/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "stateful_predicate" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/traits/stateful_predicate/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub trait StatefulPred { 2 | type Input; 3 | fn count(&self) -> usize; 4 | fn next(&mut self); 5 | fn pred(&self, x: &Self::Input) -> bool; 6 | fn reset(&mut self); 7 | } 8 | -------------------------------------------------------------------------------- /crates/traits/usize_group_by/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "usize_group_by" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/traits/usize_group_by/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! イテレータのグルーピング。 2 | 3 | /// イテレータのグルーピング。 4 | /// 5 | /// # See also 6 | /// [`GroupBy`] 7 | /// 8 | /// [`GroupBy`]: trait.GroupBy.html 9 | pub trait UsizeGroupBy { 10 | /// # Examples 11 | /// ``` 12 | /// use nekolib::traits::UsizeGroupBy; 13 | /// 14 | /// let a = vec![1, 4, 3, -5, -6, 0, 2, -2, 3]; 15 | /// let g = a.iter().copied().usize_group_by(|&ai: &i32| ai.rem_euclid(3) as usize); 16 | /// 17 | /// assert_eq!(g.len(), 3); 18 | /// assert_eq!(g[0], [3, -6, 0, 3]); 19 | /// assert_eq!(g[1], [1, 4, -5, -2]); 20 | /// assert_eq!(g[2], [2]); 21 | /// ``` 22 | fn usize_group_by(self, index: impl FnMut(&V) -> usize) -> Vec>; 23 | } 24 | 25 | impl> UsizeGroupBy for I { 26 | fn usize_group_by(self, mut index: impl FnMut(&V) -> usize) -> Vec> { 27 | let mut res: Vec> = vec![]; 28 | for v in self { 29 | let i = index(&v); 30 | if i >= res.len() { 31 | res.resize_with(i + 1, Default::default); 32 | } 33 | res[i].push(v); 34 | } 35 | res 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /crates/utils/ascii/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ascii" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/utils/ascii/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub const ASCII /* _ */: u128 = 0xffffffffffffffffffffffffffffffff; 2 | pub const ASCII_ALPHABETIC /* _ */: u128 = 0x07fffffe07fffffe0000000000000000; 3 | pub const ASCII_ALPHANUMERIC /* _ */: u128 = 0x07fffffe07fffffe03ff000000000000; 4 | pub const ASCII_CONTROL /* _ */: u128 = 0x800000000000000000000000ffffffff; 5 | pub const ASCII_DIGIT /* _ */: u128 = 0x000000000000000003ff000000000000; 6 | pub const ASCII_GRAPHIC /* _ */: u128 = 0x7ffffffffffffffffffffffe00000000; 7 | pub const ASCII_HEXDIGIT /* _ */: u128 = 0x0000007e0000007e03ff000000000000; 8 | pub const ASCII_LOWERCASE /* _ */: u128 = 0x07fffffe000000000000000000000000; 9 | pub const ASCII_PUNCTUATION /* _ */: u128 = 0x78000001f8000001fc00fffe00000000; 10 | pub const ASCII_UPPERCASE /* _ */: u128 = 0x0000000007fffffe0000000000000000; 11 | pub const ASCII_WHITESPACE /* _ */: u128 = 0x00000000000000000000000100003600; 12 | 13 | pub fn charset(b: &[u8]) -> u128 { 14 | let mut res = 0_u128; 15 | for &bi in b { 16 | res |= 1 << bi; 17 | } 18 | res 19 | } 20 | -------------------------------------------------------------------------------- /crates/utils/bitop/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bitop" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/utils/buf_range/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "buf_range" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /crates/utils/e_macro/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "e_macro" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/utils/e_macro/src/lib.rs: -------------------------------------------------------------------------------- 1 | /// デバッグ用マクロ。 2 | /// 3 | /// debug 時は `eprintln!(...)` に展開され、release 時は `()` に展開される。 4 | /// 5 | /// # Examples 6 | /// ``` 7 | /// use nekolib::e; 8 | /// 9 | /// e!("{:?}", (0..100).collect::>()); 10 | /// ``` 11 | #[cfg(debug_assertions)] 12 | #[macro_export] 13 | macro_rules! e { 14 | ( $($arg:tt)* ) => { eprintln!($($arg)*) }; 15 | } 16 | 17 | #[cfg(not(debug_assertions))] 18 | #[macro_export] 19 | macro_rules! e { 20 | ( $($arg:tt)* ) => { 21 | () 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /crates/utils/hexdump/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hexdump" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/utils/make_minmax/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "make_minmax" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/utils/make_minmax/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub trait MakeMin: PartialOrd + Sized { 2 | fn make_min(&mut self, other: Self) -> bool { 3 | let tmp = *self > other; 4 | if tmp { 5 | *self = other; 6 | } 7 | tmp 8 | } 9 | } 10 | 11 | pub trait MakeMax: PartialOrd + Sized { 12 | fn make_max(&mut self, other: Self) -> bool { 13 | let tmp = *self < other; 14 | if tmp { 15 | *self = other; 16 | } 17 | tmp 18 | } 19 | } 20 | 21 | impl MakeMin for T {} 22 | impl MakeMax for T {} 23 | 24 | #[test] 25 | fn test() { 26 | let mut a = 10_i32; 27 | a.make_max(20); 28 | assert_eq!(a, 20); 29 | a.make_max(15); 30 | assert_eq!(a, 20); 31 | a.make_min(10); 32 | assert_eq!(a, 10); 33 | a.make_min(15); 34 | assert_eq!(a, 10); 35 | } 36 | -------------------------------------------------------------------------------- /crates/utils/op_add/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "op_add" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | binop = { path = "../../traits/binop" } 11 | additive = { path = "../../traits/additive" } 12 | -------------------------------------------------------------------------------- /crates/utils/op_add/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 加法に関する wrapper クラス。 2 | 3 | use std::fmt::Debug; 4 | 5 | use additive::{AddAssoc, AddComm, Zero}; 6 | use binop::{Associative, Commutative, Identity, Magma, PartialRecip, Recip}; 7 | 8 | /// 和を返す演算を持つ。 9 | /// 10 | /// [`std::ops::Add`](https://doc.rust-lang.org/std/ops/trait.Add.html) により定義される。 11 | /// 単位元は [`Zero`]、逆元は [`std::ops::Neg`](https://doc.rust-lang.org/std/ops/trait.Neg.html) で定義する。 12 | /// 結合法則を満たすときは [`AddAssoc`]、交換法則を満たすときは [`AddComm`] を実装することで示す。 13 | /// 14 | /// [`Zero`]: ../../traits/additive/trait.Zero.html 15 | /// [`AddAssoc`]: ../../traits/additive/trait.AddAssoc.html 16 | /// [`AddComm`]: ../../traits/additive/trait.AddComm.html 17 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 18 | pub enum OpAdd { 19 | OpAddV, 20 | _Marker(T), 21 | } 22 | pub use OpAdd::OpAddV; 23 | 24 | impl Default for OpAdd { 25 | fn default() -> Self { OpAddV } 26 | } 27 | 28 | use std::ops::{Add, Neg}; 29 | 30 | impl Magma for OpAdd 31 | where 32 | T: Add + Eq + Sized, 33 | { 34 | type Set = T; 35 | fn op(&self, x: Self::Set, y: Self::Set) -> Self::Set { x + y } 36 | } 37 | impl Identity for OpAdd 38 | where 39 | T: Add + Eq + Sized + Zero, 40 | { 41 | fn id(&self) -> Self::Set { T::zero() } 42 | } 43 | impl PartialRecip for OpAdd 44 | where 45 | T: Add + Eq + Sized + Neg, 46 | { 47 | fn partial_recip(&self, x: Self::Set) -> Option { Some(-x) } 48 | } 49 | impl Recip for OpAdd 50 | where 51 | T: Add + Eq + Sized + Neg, 52 | { 53 | fn recip(&self, x: Self::Set) -> Self::Set { -x } 54 | } 55 | impl Associative for OpAdd where T: Add + Eq + Sized + AddAssoc 56 | {} 57 | impl Commutative for OpAdd where T: Add + Eq + Sized + AddComm {} 58 | -------------------------------------------------------------------------------- /crates/utils/op_add_count/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "op_add_count" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | additive = { path = "../../traits/additive" } 10 | binop = { path = "../../traits/binop" } 11 | -------------------------------------------------------------------------------- /crates/utils/op_add_count/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 加法に関する wrapper クラス。 2 | 3 | use std::fmt::Debug; 4 | 5 | use additive::{AddAssoc, AddComm, Zero}; 6 | use binop::{Associative, Commutative, Identity, Magma}; 7 | 8 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 9 | pub enum OpAddCount { 10 | OpAddCountV, 11 | _Marker(T), 12 | } 13 | pub use OpAddCount::OpAddCountV; 14 | 15 | impl Default for OpAddCount { 16 | fn default() -> Self { OpAddCountV } 17 | } 18 | 19 | use std::ops::Add; 20 | 21 | impl Magma for OpAddCount 22 | where 23 | T: Add + Eq + Sized, 24 | { 25 | type Set = (T, T); 26 | fn op(&self, (xv, xc): Self::Set, (yv, yc): Self::Set) -> Self::Set { 27 | (xv + yv, xc + yc) 28 | } 29 | } 30 | impl Identity for OpAddCount 31 | where 32 | T: Add + Eq + Sized + Zero, 33 | { 34 | fn id(&self) -> Self::Set { (T::zero(), T::zero()) } 35 | } 36 | impl Associative for OpAddCount where 37 | T: Add + Eq + Sized + AddAssoc 38 | { 39 | } 40 | impl Commutative for OpAddCount where 41 | T: Add + Eq + Sized + AddComm 42 | { 43 | } 44 | -------------------------------------------------------------------------------- /crates/utils/op_add_on_op_add_count/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "op_add_on_op_add_count" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | action = { path = "../../traits/action" } 10 | additive = { path = "../../traits/additive" } 11 | op_add = { path = "../op_add" } 12 | op_add_count = { path = "../op_add_count" } 13 | -------------------------------------------------------------------------------- /crates/utils/op_add_on_op_add_count/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Debug; 2 | use std::ops::{Add, Mul}; 3 | 4 | use action::MonoidAction; 5 | use additive::{AddAssoc, Zero}; 6 | use op_add::OpAdd; 7 | use op_add_count::OpAddCount; 8 | 9 | #[derive(Clone, Copy, Debug, Default)] 10 | pub struct OpAddOnOpAddCount { 11 | op_add: OpAdd, 12 | op_add_count: OpAddCount, 13 | } 14 | 15 | impl MonoidAction for OpAddOnOpAddCount 16 | where 17 | T: Ord 18 | + Eq 19 | + Clone 20 | + Add 21 | + AddAssoc 22 | + Mul 23 | + Zero 24 | + Sized, 25 | { 26 | type Operand = OpAddCount; 27 | type Operator = OpAdd; 28 | fn operand(&self) -> &Self::Operand { &self.op_add_count } 29 | fn operator(&self) -> &Self::Operator { &self.op_add } 30 | fn act(&self, (xv, xc): (T, T), op: T) -> (T, T) { 31 | let xv = xv + op * xc.clone(); 32 | (xv, xc) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /crates/utils/op_add_on_op_max/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "op_add_on_op_max" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | op_add = { path = "../op_add" } 10 | op_max = { path = "../op_max" } 11 | additive = { path = "../../traits/additive" } 12 | binop = { path = "../../traits/binop" } 13 | min = { path = "../../traits/min" } 14 | action = { path = "../../traits/action" } 15 | -------------------------------------------------------------------------------- /crates/utils/op_add_on_op_max/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Debug; 2 | use std::ops::Add; 3 | 4 | use action::MonoidAction; 5 | use additive::{AddAssoc, Zero}; 6 | use binop::Magma; 7 | use min::Min; 8 | use op_add::OpAdd; 9 | use op_max::OpMax; 10 | 11 | #[derive(Clone, Copy, Debug, Default)] 12 | pub struct OpAddOnOpMax { 13 | op_add: OpAdd, 14 | op_max: OpMax, 15 | } 16 | 17 | impl + AddAssoc + Zero + Min + Sized> MonoidAction 18 | for OpAddOnOpMax 19 | { 20 | type Operand = OpMax; 21 | type Operator = OpAdd; 22 | fn operand(&self) -> &Self::Operand { &self.op_max } 23 | fn operator(&self) -> &Self::Operator { &self.op_add } 24 | fn act(&self, x: T, op: T) -> T { self.op_add.op(x, op) } 25 | } 26 | -------------------------------------------------------------------------------- /crates/utils/op_add_on_op_min/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "op_add_on_op_min" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | op_add = { path = "../op_add" } 10 | op_min = { path = "../op_min" } 11 | additive = { path = "../../traits/additive" } 12 | binop = { path = "../../traits/binop" } 13 | max = { path = "../../traits/max" } 14 | action = { path = "../../traits/action" } 15 | -------------------------------------------------------------------------------- /crates/utils/op_add_on_op_min/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Debug; 2 | use std::ops::Add; 3 | 4 | use action::MonoidAction; 5 | use additive::{AddAssoc, Zero}; 6 | use binop::Magma; 7 | use max::Max; 8 | use op_add::OpAdd; 9 | use op_min::OpMin; 10 | 11 | #[derive(Clone, Copy, Debug, Default)] 12 | pub struct OpAddOnOpMin { 13 | op_add: OpAdd, 14 | op_min: OpMin, 15 | } 16 | 17 | impl + AddAssoc + Zero + Max + Sized> MonoidAction 18 | for OpAddOnOpMin 19 | { 20 | type Operand = OpMin; 21 | type Operator = OpAdd; 22 | fn operand(&self) -> &Self::Operand { &self.op_min } 23 | fn operator(&self) -> &Self::Operator { &self.op_add } 24 | fn act(&self, x: T, op: T) -> T { self.op_add.op(x, op) } 25 | } 26 | -------------------------------------------------------------------------------- /crates/utils/op_affine/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "op_affine" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | additive = { path = "../../traits/additive" } 10 | multiplicative = { path = "../../traits/multiplicative" } 11 | binop = { path = "../../traits/binop" } 12 | -------------------------------------------------------------------------------- /crates/utils/op_affine/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 加法に関する wrapper クラス。 2 | 3 | use std::fmt::Debug; 4 | 5 | use additive::{AddAssoc, Zero}; 6 | use binop::{Associative, Identity, Magma}; 7 | use multiplicative::One; 8 | 9 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 10 | pub enum OpAffine { 11 | OpAffineV, 12 | _Marker(T), 13 | } 14 | pub use OpAffine::OpAffineV; 15 | 16 | impl Default for OpAffine { 17 | fn default() -> Self { OpAffineV } 18 | } 19 | 20 | use std::ops::{Add, Mul}; 21 | 22 | impl Magma for OpAffine 23 | where 24 | T: Add + Mul + Eq + Clone + Sized, 25 | { 26 | type Set = (T, T); 27 | fn op(&self, (x1, x0): Self::Set, (y1, y0): Self::Set) -> Self::Set { 28 | // c(ax+b) + d = acx + (bc+d) 29 | let z1 = x1 * y1.clone(); 30 | let z0 = x0 * y1 + y0; 31 | (z1, z0) 32 | } 33 | } 34 | impl Identity for OpAffine 35 | where 36 | T: Add + Mul + Eq + Clone + Sized + Zero + One, 37 | { 38 | fn id(&self) -> Self::Set { (T::one(), T::zero()) } 39 | } 40 | impl Associative for OpAffine where 41 | T: Add + Mul + Eq + Clone + Sized + AddAssoc 42 | { 43 | } 44 | -------------------------------------------------------------------------------- /crates/utils/op_affine_on_op_add_count/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "op_affine_on_op_add_count" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | action = { path = "../../traits/action" } 10 | additive = { path = "../../traits/additive" } 11 | multiplicative = { path = "../../traits/multiplicative" } 12 | op_add_count = { path = "../op_add_count" } 13 | op_affine = { path = "../op_affine" } 14 | -------------------------------------------------------------------------------- /crates/utils/op_affine_on_op_add_count/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Debug; 2 | use std::ops::{Add, Mul}; 3 | 4 | use action::MonoidAction; 5 | use additive::{AddAssoc, Zero}; 6 | use multiplicative::One; 7 | use op_add_count::OpAddCount; 8 | use op_affine::OpAffine; 9 | 10 | #[derive(Clone, Copy, Debug, Default)] 11 | pub struct OpAffineOnOpAddCount { 12 | op_affine: OpAffine, 13 | op_add_count: OpAddCount, 14 | } 15 | 16 | impl MonoidAction for OpAffineOnOpAddCount 17 | where 18 | T: Ord 19 | + Eq 20 | + Clone 21 | + Add 22 | + AddAssoc 23 | + Mul 24 | + Zero 25 | + One 26 | + Sized, 27 | { 28 | type Operand = OpAddCount; 29 | type Operator = OpAffine; 30 | fn operand(&self) -> &Self::Operand { &self.op_add_count } 31 | fn operator(&self) -> &Self::Operator { &self.op_affine } 32 | fn act(&self, (xv, xc): (T, T), (y1, y0): (T, T)) -> (T, T) { 33 | // Sum(ax+b) = a Sum(x) + b Sum(1) 34 | let xv = y1 * xv + y0 * xc.clone(); 35 | (xv, xc) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /crates/utils/op_closure/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "op_closure" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | binop = { path = "../../traits/binop" } 10 | -------------------------------------------------------------------------------- /crates/utils/op_closure/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! クロージャの wrapper クラス。 2 | 3 | use std::fmt::Debug; 4 | 5 | use binop::{Associative, Identity, Magma}; 6 | 7 | /// 任意の結合的な演算を持つ。 8 | /// 9 | /// 結合性については使用者側に保証してもらう。 10 | /// 11 | /// # Examples 12 | /// ``` 13 | /// use std::cell::RefCell; 14 | /// 15 | /// use nekolib::traits::{Magma, Identity}; 16 | /// use nekolib::utils::OpClosure; 17 | /// 18 | /// let runtime_mod = 10; 19 | /// let op_memo = RefCell::new(vec![]); 20 | /// let id_times = RefCell::new(0); 21 | /// let op_cl = OpClosure::new(|x: i32, y| { 22 | /// op_memo.borrow_mut().push((x, y)); 23 | /// (x + y).rem_euclid(runtime_mod) 24 | /// }, || { 25 | /// *id_times.borrow_mut() += 1; 26 | /// 0 27 | /// }); 28 | /// 29 | /// assert_eq!(op_cl.op(1, 9), 0); 30 | /// assert_eq!(op_cl.op(3, 8), 1); 31 | /// assert_eq!(op_cl.op(-5, -3), 2); 32 | /// assert_eq!(op_cl.id(), 0); 33 | /// 34 | /// assert_eq!(*op_memo.borrow(), [(1, 9), (3, 8), (-5, -3)]); 35 | /// assert_eq!(*id_times.borrow(), 1); 36 | /// ``` 37 | #[derive(Clone, Copy, Debug, Default)] 38 | pub struct OpClosure T, Id: Fn() -> T>(Op, Id); 39 | 40 | impl T, Id: Fn() -> T> OpClosure { 41 | pub fn new(op: Op, id: Id) -> Self { Self(op, id) } 42 | } 43 | 44 | impl T, Id: Fn() -> T> Magma for OpClosure { 45 | type Set = T; 46 | fn op(&self, lhs: T, rhs: T) -> T { (self.0)(lhs, rhs) } 47 | } 48 | 49 | impl T, Id: Fn() -> T> Identity 50 | for OpClosure 51 | { 52 | fn id(&self) -> T { (self.1)() } 53 | } 54 | 55 | impl T, Id: Fn() -> T> Associative 56 | for OpClosure 57 | { 58 | } 59 | -------------------------------------------------------------------------------- /crates/utils/op_closure_on_op_closure/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "op_closure_on_op_closure" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | op_closure = { path = "../op_closure" } 10 | action = { path = "../../traits/action" } 11 | -------------------------------------------------------------------------------- /crates/utils/op_closure_on_op_closure/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Debug; 2 | 3 | use action::MonoidAction; 4 | use op_closure::OpClosure; 5 | 6 | #[derive(Clone, Copy, Debug, Default)] 7 | pub struct OpClosureOnOpClosure 8 | where 9 | OpT: Fn(T, T) -> T, 10 | IdT: Fn() -> T, 11 | OpU: Fn(U, U) -> U, 12 | IdU: Fn() -> U, 13 | Act: Fn(T, U) -> T, 14 | { 15 | operator: OpClosure, 16 | operand: OpClosure, 17 | act: Act, 18 | } 19 | 20 | impl MonoidAction 21 | for OpClosureOnOpClosure 22 | where 23 | T: Eq + Sized, 24 | OpT: Fn(T, T) -> T, 25 | IdT: Fn() -> T, 26 | U: Eq + Sized, 27 | OpU: Fn(U, U) -> U, 28 | IdU: Fn() -> U, 29 | Act: Fn(T, U) -> T, 30 | { 31 | type Operand = OpClosure; 32 | type Operator = OpClosure; 33 | fn operand(&self) -> &Self::Operand { &self.operand } 34 | fn operator(&self) -> &Self::Operator { &self.operator } 35 | fn act(&self, x: T, op: U) -> T { (self.act)(x, op) } 36 | } 37 | 38 | impl 39 | OpClosureOnOpClosure 40 | where 41 | T: Eq + Sized, 42 | OpT: Fn(T, T) -> T, 43 | IdT: Fn() -> T, 44 | U: Eq + Sized, 45 | OpU: Fn(U, U) -> U, 46 | IdU: Fn() -> U, 47 | Act: Fn(T, U) -> T, 48 | { 49 | pub fn new( 50 | operand: OpClosure, 51 | operator: OpClosure, 52 | act: Act, 53 | ) -> Self { 54 | Self { operand, operator, act } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /crates/utils/op_gcd/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "op_gcd" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | binop = { path = "../../traits/binop" } 10 | gcd = { path = "../../math/gcd" } 11 | additive = { path = "../../traits/additive" } 12 | -------------------------------------------------------------------------------- /crates/utils/op_gcd/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Debug; 2 | 3 | use additive::Zero; 4 | use binop::{Associative, Commutative, Identity, Magma}; 5 | use gcd::Gcd; 6 | 7 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 8 | pub enum OpGcd { 9 | OpGcdV, 10 | _Marker(T), 11 | } 12 | pub use OpGcd::OpGcdV; 13 | 14 | impl Default for OpGcd { 15 | fn default() -> Self { OpGcdV } 16 | } 17 | 18 | impl Magma for OpGcd 19 | where 20 | T: Gcd + Eq + Sized, 21 | { 22 | type Set = T; 23 | fn op(&self, x: Self::Set, y: Self::Set) -> Self::Set { x.gcd(y) } 24 | } 25 | impl Identity for OpGcd 26 | where 27 | T: Gcd + Eq + Zero + Sized, 28 | { 29 | fn id(&self) -> Self::Set { T::zero() } 30 | } 31 | 32 | impl Associative for OpGcd where T: Gcd + Eq + Sized {} 33 | impl Commutative for OpGcd where T: Gcd + Eq + Sized {} 34 | -------------------------------------------------------------------------------- /crates/utils/op_max/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "op_max" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | binop = { path = "../../traits/binop" } 11 | min = { path = "../../traits/min" } 12 | -------------------------------------------------------------------------------- /crates/utils/op_max/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 最大値に関する wrapper クラス。 2 | 3 | use std::fmt::Debug; 4 | 5 | use binop::{Associative, Commutative, Identity, Magma}; 6 | use min::Min; 7 | 8 | /// 最大値を返す演算を持つ。 9 | /// 10 | /// 単位元は [`Min`] で定義する。 11 | /// 12 | /// [`Min`]: ../../traits/min/trait.Min.html 13 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 14 | pub enum OpMax { 15 | OpMaxV, 16 | _Marker(T), 17 | } 18 | pub use OpMax::OpMaxV; 19 | 20 | impl Default for OpMax { 21 | fn default() -> Self { OpMaxV } 22 | } 23 | 24 | impl Magma for OpMax 25 | where 26 | T: Ord + Eq + Sized, 27 | { 28 | type Set = T; 29 | fn op(&self, x: Self::Set, y: Self::Set) -> Self::Set { x.max(y) } 30 | } 31 | impl Identity for OpMax 32 | where 33 | T: Ord + Eq + Sized + Min, 34 | { 35 | fn id(&self) -> Self::Set { ::min() } 36 | } 37 | 38 | impl Associative for OpMax where T: Ord + Eq + Sized {} 39 | impl Commutative for OpMax where T: Ord + Eq + Sized {} 40 | -------------------------------------------------------------------------------- /crates/utils/op_min/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "op_min" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | binop = { path = "../../traits/binop" } 11 | max = { path = "../../traits/max" } 12 | -------------------------------------------------------------------------------- /crates/utils/op_min/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! 最小値に関する wrapper クラス。 2 | 3 | use std::fmt::Debug; 4 | 5 | use binop::{Associative, Commutative, Identity, Magma}; 6 | use max::Max; 7 | 8 | /// 最小値を返す演算を持つ。 9 | /// 10 | /// 単位元は [`Max`] で定義する。 11 | /// 12 | /// [`Max`]: ../../traits/max/trait.Max.html 13 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 14 | pub enum OpMin { 15 | OpMinV, 16 | _Marker(T), 17 | } 18 | pub use OpMin::OpMinV; 19 | 20 | impl Default for OpMin { 21 | fn default() -> Self { OpMinV } 22 | } 23 | 24 | impl Magma for OpMin 25 | where 26 | T: Ord + Eq + Sized, 27 | { 28 | type Set = T; 29 | fn op(&self, x: Self::Set, y: Self::Set) -> Self::Set { x.min(y) } 30 | } 31 | impl Identity for OpMin 32 | where 33 | T: Ord + Eq + Sized + Max, 34 | { 35 | fn id(&self) -> Self::Set { ::max() } 36 | } 37 | 38 | impl Associative for OpMin where T: Ord + Eq + Sized {} 39 | impl Commutative for OpMin where T: Ord + Eq + Sized {} 40 | -------------------------------------------------------------------------------- /crates/utils/op_mul/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "op_mul" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | binop = { path = "../../traits/binop" } 11 | multiplicative = { path = "../../traits/multiplicative" } 12 | op_add = { path = "../op_add" } 13 | -------------------------------------------------------------------------------- /crates/utils/op_roll_hash/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "op_roll_hash" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | binop = { path = "../../traits/binop" } 11 | -------------------------------------------------------------------------------- /crates/utils/op_roll_hash/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! ローリングハッシュに関する wrapper クラス。 2 | 3 | use std::fmt::Debug; 4 | 5 | use binop::{Associative, Identity, Magma}; 6 | 7 | /// 文字列連結をローリングハッシュで行う演算を持つ。 8 | /// 9 | /// # Examples 10 | /// ``` 11 | /// use nekolib::traits::Magma; 12 | /// use nekolib::utils::OpRollHash; 13 | /// 14 | /// let op_rh = OpRollHash::<998244353>::default(); 15 | /// let value_of = |s| op_rh.value_of(s); 16 | /// let op = |x, y| op_rh.op(x, y); 17 | /// 18 | /// let abr = value_of("abr"); 19 | /// let a = value_of("a"); 20 | /// let abra = value_of("abra"); 21 | /// assert_eq!(op(abr, a), abra); 22 | /// 23 | /// let s = "abracadabra"; 24 | /// assert_eq!(value_of(&s[0..4]), abra); 25 | /// assert_eq!(value_of(&s[7..11]), abra); 26 | /// assert_ne!(value_of(&s[1..5]), abra); 27 | /// assert_eq!(value_of(s), op(op(abra, value_of("cad")), abra)); 28 | /// ``` 29 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 30 | pub enum OpRollHash { 31 | OpRollHashV, 32 | } 33 | pub use OpRollHash::OpRollHashV; 34 | 35 | impl Default for OpRollHash { 36 | fn default() -> Self { OpRollHashV } 37 | } 38 | 39 | impl Magma for OpRollHash { 40 | type Set = (u64, u64); 41 | fn op(&self, (hx, lx): Self::Set, (hy, ly): Self::Set) -> Self::Set { 42 | ((hx * ly + hy) % B, (lx * ly) % B) 43 | } 44 | } 45 | 46 | impl Identity for OpRollHash { 47 | fn id(&self) -> Self::Set { (0, 1) } 48 | } 49 | 50 | impl Associative for OpRollHash {} 51 | 52 | impl OpRollHash { 53 | #[must_use] 54 | pub fn value_of(&self, s: &str) -> ::Set { 55 | s.chars().fold((0, 0), |acc, x| self.op(acc, (x as u64, B))) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /crates/utils/output/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "output" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/utils/rand_gen_macro/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rand_gen_macro" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | rand = "0.8.5" 10 | rand_chacha = "0.3.1" 11 | bitop = { path = "../bitop" } 12 | -------------------------------------------------------------------------------- /crates/utils/scan_macro/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "scan_macro" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /crates/utils/scanner/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "scanner" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /katex-header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 33 | -------------------------------------------------------------------------------- /notes/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "notes" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /notes/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! テスト 2 | 3 | /// テスト 4 | 5 | /// add 6 | /// 7 | /// 関数サンプル 8 | pub fn add(left: usize, right: usize) -> usize { left + right } 9 | 10 | #[cfg(test)] 11 | mod tests { 12 | use super::*; 13 | 14 | #[test] 15 | fn it_works() { 16 | let result = add(2, 2); 17 | assert_eq!(result, 4); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /script/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "script" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | base16 = "0.2.1" 11 | bishop = "0.3.4" 12 | 13 | [workspace] 14 | -------------------------------------------------------------------------------- /script/src/bin/revision-art.rs: -------------------------------------------------------------------------------- 1 | use base16::decode; 2 | use bishop::{BishopArt, DrawingOptions}; 3 | 4 | fn main() { 5 | let sha_enc = std::env::args().nth(1).unwrap(); 6 | let sha = decode(&sha_enc).unwrap(); 7 | let mut ba = BishopArt::with_size(16, 8).unwrap(); 8 | ba.input(sha); 9 | 10 | // " .o+=*BOX@%&#/^SE" 11 | let chars: Vec<_> = " .:-+=*ox#O8X%@^$".chars().collect(); 12 | 13 | let content = format!( 14 | r" 15 | ## Revision 16 | [`{0}`](https://github.com/rsk0315/library-rs/tree/{0}) 17 | 18 | ```text 19 | {1}``` 20 | ", 21 | sha_enc, 22 | ba.draw_with_opts(&DrawingOptions { chars, ..Default::default() }) 23 | ); 24 | 25 | for line in content.lines() { 26 | println!("//! {}", line); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /static/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | # See https://doc.rust-lang.org/cargo/reference/config.html 2 | 3 | [alias] 4 | d = "doc --no-deps" 5 | p = "clippy -- -W clippy::pedantic -A clippy::doc_markdown -A clippy::module_name_repetitions" 6 | 7 | [build] 8 | rustdocflags = [ 9 | "--html-in-header", "katex-header.html", 10 | "--html-in-header", "lato-header.html", 11 | "--html-in-header", "ferris-in-doc.html", 12 | ] 13 | -------------------------------------------------------------------------------- /static/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | 'nekolib', 4 | 'nekolib-verify', 5 | 'nekolib-notes', 6 | ] 7 | -------------------------------------------------------------------------------- /static/clippy.toml: -------------------------------------------------------------------------------- 1 | single-char-binding-names-threshold = 20 2 | type-complexity-threshold = 10000 3 | -------------------------------------------------------------------------------- /static/ferris-in-doc.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 54 | -------------------------------------------------------------------------------- /static/images/tree_cata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsk0315/library-rs/191796ee2e0b077542794399c959098a6563195c/static/images/tree_cata.png -------------------------------------------------------------------------------- /static/katex-header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 33 | -------------------------------------------------------------------------------- /static/lato-header.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /static/nekolib-notes/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "nekolib-notes" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | proconio = "0.4.3" 11 | -------------------------------------------------------------------------------- /static/nekolib-notes/ferris-in-doc.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /static/nekolib-notes/katex-header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 33 | -------------------------------------------------------------------------------- /static/nekolib-notes/lato-header.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/nekolib-notes/src/debug.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../debug.md")] 2 | -------------------------------------------------------------------------------- /static/nekolib-notes/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! [`nekolib`] に入れにくい形のメモたち。考察の方針関連など。 2 | //! 3 | //! [`nekolib`]: ../nekolib/index.html 4 | 5 | pub mod debug; 6 | pub mod range_add_on_the_fly; 7 | -------------------------------------------------------------------------------- /static/nekolib-verify/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "nekolib-verify" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | toml = "0.5.6" 11 | serde = { version = "1.0.116", features = ["derive"] } 12 | serde_json = "1.0.58" 13 | -------------------------------------------------------------------------------- /static/nekolib-verify/ferris-in-doc.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /static/nekolib-verify/katex-header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | -------------------------------------------------------------------------------- /static/nekolib-verify/lato-header.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/nekolib-verify/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! [`nekolib`] の verify に関するもの。 2 | //! 3 | //! そのうちちゃんと作ります。 4 | //! 5 | //! [`nekolib`]: ../nekolib/index.html 6 | //! 7 | //! `library-rs` では verify をしているのですが、 8 | //! いまいち運用しやすい形式を確立できていないので、早くなんとかしたいです。 9 | //! 10 | //! どの問題で何を verify したかとかを見やすい形式で可視化できたらいいよね。 11 | //! たとえば、次のような形式のドキュメントを生成しやすいように作ってみる? 12 | //! 13 | //! --- 14 | //! 15 | //! # Sample (verifier) 16 | //! 17 | //! `some_algo` の verify をします。 18 | //! 19 | //! ## Verified by 20 | //! - ソルバへのリンク 1 (passing/failing) 21 | //! - ソルバへのリンク 2 (passing/failing) 22 | //! - ソルバへのリンク 3 (passing/failing) 23 | //! 24 | //! --- 25 | //! 26 | //! # Sample (solver for algo) 27 | //! 28 | //! `some_algo` を用いて問題 A を解きます。 29 | //! 30 | //! ## Solves 31 | //! - 問題 A へのリンク 32 | //! 33 | //! ## Explanations 34 | //! 解法の概要などが必要であれば書く。 35 | //! 36 | //! --- 37 | //! 38 | //! # Sample (solver for ds) 39 | //! 40 | //! トレイト `T` を実装した `some_ds` を用いて問題 B を解きます。 41 | //! 42 | //! ## Solves 43 | //! - 問題 B へのリンク 44 | //! 45 | //! ## Explanations 46 | //! 解法の概要などが必要であれば書く。 47 | 48 | #[cfg(test)] 49 | mod tests { 50 | #[test] 51 | fn it_works() { 52 | assert_eq!(2 + 2, 4); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /static/nekolib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "nekolib" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | rand = "0.8.5" 11 | rand_chacha = "0.3.1" 12 | 13 | [dev-dependencies] 14 | lazy_static = "1.4.0" 15 | -------------------------------------------------------------------------------- /static/nekolib/ferris-in-doc.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /static/nekolib/katex-header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | -------------------------------------------------------------------------------- /static/nekolib/lato-header.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/nekolib/src/algo.rs: -------------------------------------------------------------------------------- 1 | //! アルゴリズムたち。 2 | //! 3 | //! ここに何かを書く。 4 | pub mod bisect_; 5 | pub mod exact_cover; 6 | pub mod extremum; 7 | pub mod extremum_float; 8 | pub mod hilbert_mo_; 9 | pub mod index_order; 10 | pub mod inversion; 11 | pub mod karatsuba; 12 | pub mod larsch; 13 | pub mod majority_; 14 | pub mod minmax; 15 | pub mod mo; 16 | pub mod ordered_hash_; 17 | pub mod parallel_bisect; 18 | pub mod permutation; 19 | pub mod rle; 20 | pub mod tortoise_hare; 21 | pub mod window_bisect; 22 | 23 | #[doc(inline)] 24 | pub use bisect_::{bisect, bisect_slice}; 25 | #[doc(inline)] 26 | pub use exact_cover::ExactCover; 27 | #[doc(inline)] 28 | pub use extremum::{extremum, extremum_slice}; 29 | #[doc(inline)] 30 | pub use extremum_float::extremum_float; 31 | #[doc(inline)] 32 | pub use hilbert_mo_::hilbert_mo; 33 | #[doc(inline)] 34 | pub use index_order::{index_order_by, index_order_by_key}; 35 | #[doc(inline)] 36 | pub use inversion::Inversion; 37 | #[doc(inline)] 38 | pub use karatsuba::convolve; 39 | #[doc(inline)] 40 | pub use larsch::Larsch; 41 | #[doc(inline)] 42 | pub use majority_::majority; 43 | #[doc(inline)] 44 | pub use minmax::{minmax, minmax_by, minmax_by_key}; 45 | #[doc(inline)] 46 | pub use mo::mo; 47 | #[doc(inline)] 48 | pub use ordered_hash_::ordered_hash; 49 | #[doc(inline)] 50 | pub use parallel_bisect::parallel_bisect; 51 | #[doc(inline)] 52 | pub use permutation::{ 53 | next_permutation, prev_permutation, Backward, Forward, Permutations, 54 | }; 55 | #[doc(inline)] 56 | pub use rle::{Rle, RleBy, RleByKey}; 57 | #[doc(inline)] 58 | pub use tortoise_hare::{cycle_mu_lambda, cycle_nth}; 59 | #[doc(inline)] 60 | pub use window_bisect::window_bisect; 61 | -------------------------------------------------------------------------------- /static/nekolib/src/graph.rs: -------------------------------------------------------------------------------- 1 | //! グラフに関するものたち。 2 | //! 3 | //! ここに何かを書く。 4 | pub mod adjlist; 5 | pub mod dijkstra_; 6 | pub mod dinic_; 7 | pub mod functional_graph; 8 | pub mod hld; 9 | pub mod scc_; 10 | pub mod tree_cata; 11 | 12 | #[doc(inline)] 13 | pub use adjlist::from_root; 14 | #[doc(inline)] 15 | pub use dijkstra_::dijkstra; 16 | #[doc(inline)] 17 | pub use dinic_::dinic; 18 | #[doc(inline)] 19 | pub use functional_graph::FunctionalGraph; 20 | #[doc(inline)] 21 | pub use hld::{Direction, HlEdge, Hld}; 22 | #[doc(inline)] 23 | pub use scc_::scc; 24 | #[doc(inline)] 25 | pub use tree_cata::TreeCata; 26 | -------------------------------------------------------------------------------- /static/nekolib/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! ねこちゃんライブラリ。 2 | //! 3 | //! [![verify](https://github.com/rsk0315/library-rs/workflows/verify/badge.svg)](https://github.com/rsk0315/library-rs/actions/workflows/verify.yml) 4 | //! [![doctest](https://github.com/rsk0315/library-rs/workflows/test%20--doc/badge.svg)](https://github.com/rsk0315/library-rs/actions/workflows/doc_test.yml) 5 | //! [![unittest](https://github.com/rsk0315/library-rs/workflows/test%20--lib/badge.svg)](https://github.com/rsk0315/library-rs/actions/workflows/unit_test.yml) 6 | //! 7 | //! [えびちゃん](https://twitter.com/rsk0315_h4x) の競プロライブラリですにゃ。 8 | //! 9 | //! 各種スニペットを個別クレートとして分けて作ったもの 10 | //! ([`library-rs`](https://github.com/rsk0315/library-rs)) 11 | //! をモジュールの形に自動変換して作られたものがこれ (`nekolib`) になります。 12 | //! `nekolib` は仮称で、よりよい名前が見つかったら変わると思います。 13 | //! 14 | //! モジュールの形に変換している理由は、主にドキュメントの見やすさのためです。 15 | //! 元コードでクレートに分けて書いている理由は、詳しくはここでは書きません[^1] 16 | //! が、 主には依存関係を書きやすかったためです。 17 | //! 18 | //! [^1]: 一度書いたところ、ここに載せるには長くなりすぎたため。 19 | //! 20 | //! # 🐱 Cat 21 | //! にゃー。 22 | // #![feature(once_cell)] 23 | -------------------------------------------------------------------------------- /static/nekolib/src/seq.rs: -------------------------------------------------------------------------------- 1 | //! 文字列アルゴリズムたち。 2 | //! 3 | //! 添字関連の事情で、`String` よりは `Vec` として作る気がしたので、 4 | //! 文字列アルゴリズムというよりは列アルゴリズムっぽい名前にしてみました。 5 | pub mod kmp; 6 | pub mod suffix_array; 7 | pub mod z_algo; 8 | 9 | #[doc(inline)] 10 | pub use kmp::KmpSearcher; 11 | #[doc(inline)] 12 | pub use suffix_array::SuffixArray; 13 | #[doc(inline)] 14 | pub use z_algo::ZSearcher; 15 | -------------------------------------------------------------------------------- /static/poem.md: -------------------------------------------------------------------------------- 1 | bundle の際、各クラス・関数の依存関係がわからないとつらいため、 2 | クレートとして分けて作りたい気持ちがあります。全部貼るのはやだなので。 3 | _Cargo.toml_ に依存関係を書いておけば、それを読んで解決すればよいためです。 4 | 5 | 一方で、コンテスト中に、どのクレートを使うかをいちいち _Cargo.toml_ 6 | に書くのは避けたいです。そこで、クレートごとに分けて作ったライブラリを、 7 | 構造を保ったままモジュールに変換して、一つのクレートとしてしまえば、 8 | ```toml 9 | nekolib = { path = "/path/to/nekolib" } 10 | ``` 11 | と書くだけで済むので、うれしいかなと思いました。コード中にも、 12 | ``` 13 | use nekolib::ds::VecSegtree; 14 | ``` 15 | のように書くだけで済み、クレート名などには気を払わなくてよくなりそうです。 16 | いちいち内部構造を思い出すのは [やだなので](https://doc.rust-jp.rs/book-ja/ch14-02-publishing-to-crates-io.html?highlight=color#pub-use%E3%81%A7%E4%BE%BF%E5%88%A9%E3%81%AA%E5%85%AC%E9%96%8Bapi%E3%82%92%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B)。 17 | 18 | 単一クレートにまとめたかったもう一つの動機として、ドキュメントの見やすさがあります。 19 | ワークスペース上に各種クレートを置いたのに対して `cargo doc` をすると、 20 | 種類の異なるクレートが Crates にまとめられてしまい、探しにくいです。 21 | 「アルゴリズム」「データ構造」「トレイト」「ユーティリティ」くらいの分類はあってほしいです。 22 | それらの各々がモジュールであれば(すなわち `mod algo; mod ds;` のようになっていれば)、 23 | ドキュメント上でも見やすくなるかなと思いました。 24 | 25 | ここまでで、次の三つが満たされたと思いました。 26 | - ライブラリ間の依存関係がわかる 27 | - コンテスト中の記述が楽 28 | - ドキュメントが見やすい 29 | 30 | なのですが、大事なことを忘れていて、コンテスト中に書いた `e.rs` や `f.rs` などが 31 | どのライブラリに依存しているかを簡単には判別できません。 32 | おそらく、モジュールに変換しない状態でも _Cargo.toml_ に書く方法ではつらい気がします。 33 | 共通の _Cargo.toml_ を使うと思うので、「E 問題で使ったライブラリは、F 問題では必要ないが 34 | F 問題でも必要だと bundler は思い込んでいる」のような状況が生じる気がします。 35 | 36 | はー、困りました。 37 | ``` 38 | use nekolib::algo::the_algo; 39 | use nekolib::ds::{first_ds, second_ds}; 40 | use nekolib::traits::{ 41 | some_trait, other_trait, yet_another_trait, 42 | one_more_trait, 43 | }; 44 | ``` 45 | のような形式のみに限ることにすれば、自前で簡単にできそうです。 46 | これらがコメントアウトされているかどうかは当面は気にしないことにします。 47 | 複数行のコメント(しかもネストが可能)は面倒ですし、まず書かないですし。 48 | 必要に迫られたら、ちゃんとした parser を書くことを検討しましょう。 49 | 50 | ところで、まだ困った問題があります。 51 | verify 用の機構もある程度は作っているのですが、 52 | 「これはこうやって verify した」という情報にドキュメント上で簡単にアクセスする方法が 53 | わからないでいます。当然自動化されてほしいのですが、少々面倒そうです。 54 | -------------------------------------------------------------------------------- /verifiers/.gitignore: -------------------------------------------------------------------------------- 1 | testcases/ 2 | -------------------------------------------------------------------------------- /verifiers/download/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "download" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | reqwest = "0.10.8" 11 | tokio = { version = "0.2.22", features = ["macros", "time"] } 12 | toml = "0.5.6" 13 | serde = { version = "1.0.116", features = ["derive"] } 14 | serde_json = "1.0.58" 15 | verify = { path = "../verify" } 16 | 17 | [[bin]] 18 | name = "download" -------------------------------------------------------------------------------- /verifiers/download/src/main.rs: -------------------------------------------------------------------------------- 1 | macro_rules! downloads { 2 | ( $( $t:ty, )* ) => { 3 | $( download::download::<$t>().await?; )* 4 | } 5 | } 6 | 7 | #[allow(clippy::wildcard_imports)] 8 | #[tokio::main] 9 | async fn main() -> Result<(), Box> { 10 | use verify::jury::*; 11 | 12 | downloads! { 13 | Aoj0000, 14 | Aoj0002, 15 | Aoj0270, 16 | Aoj0425, 17 | Aoj0564, 18 | Aoj0575, 19 | Aoj1180, 20 | Aoj2880, 21 | AojAldsOne14B, 22 | AojAldsOne14D, 23 | AojDsl1A, 24 | AojDsl1B, 25 | AojDsl2B, 26 | AojDsl2D, 27 | AojGrl1A, 28 | AojGrl3C, 29 | AojGrl6A, 30 | Yuki1601, 31 | Yuki3287, 32 | } 33 | 34 | Ok(()) 35 | } 36 | -------------------------------------------------------------------------------- /verifiers/verify/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "verify" 3 | version = "0.1.0" 4 | authors = ["rsk0315 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | toml = "0.5.6" 11 | serde = { version = "1.0.116", features = ["derive"] } 12 | serde_json = "1.0.58" 13 | scanner = { path = "../../crates/utils/scanner" } 14 | fold = { path = "../../crates/traits/fold" } 15 | fold_bisect = { path = "../../crates/traits/fold_bisect" } 16 | set_value = { path = "../../crates/traits/set_value" } 17 | op_add = { path = "../../crates/utils/op_add" } 18 | op_max = { path = "../../crates/utils/op_max" } 19 | op_min = { path = "../../crates/utils/op_min" } 20 | bisect_ = { path = "../../crates/algo/bisect_" } 21 | tortoise_hare = { path = "../../crates/algo/tortoise_hare" } 22 | additive = { path = "../../crates/traits/additive" } 23 | union-find = { path = "../../crates/ds/union_find" } 24 | disjoint-set = { path = "../../crates/traits/disjoint-set" } 25 | elastic_slice = { path = "../../crates/traits/elastic_slice" } 26 | mo = { path = "../../crates/algo/mo" } 27 | dijkstra_ = { path = "../../crates/graph/dijkstra_" } 28 | parallel_bisect = { path = "../../crates/algo/parallel_bisect" } 29 | stateful_predicate = { path = "../../crates/traits/stateful_predicate" } 30 | scc_ = { path = "../../crates/graph/scc_" } 31 | suffix_array = { path = "../../crates/seq/suffix_array" } 32 | # pat_searcher = { path = "../../crates/traits/pat_searcher" } 33 | z_algo = { path = "../../crates/seq/z_algo" } 34 | kmp = { path = "../../crates/seq/kmp" } 35 | potential_function = { path = "../../crates/traits/potential_function" } 36 | interval_set = { path = "../../crates/ds/interval_set" } 37 | dinic_ = { path = "../../crates/graph/dinic_" } 38 | 39 | [dev-dependencies] 40 | vec_segtree = { path = "../../crates/ds/vec_segtree" } 41 | union-find = { path = "../../crates/ds/union_find" } 42 | potentialized_union_find = { path = "../../crates/ds/potentialized_union_find" } 43 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury.rs: -------------------------------------------------------------------------------- 1 | macro_rules! uses { 2 | ( $( $i:ident, )* ) => { 3 | $( 4 | pub mod $i; 5 | #[doc(inline)] 6 | pub use $i::*; 7 | )* 8 | } 9 | } 10 | 11 | uses! { 12 | aoj_0000, 13 | aoj_0002, 14 | aoj_0270, 15 | aoj_0425, 16 | aoj_0564, 17 | aoj_0575, 18 | aoj_1180, 19 | aoj_2880, 20 | aoj_alds1_14_b, 21 | aoj_alds1_14_d, 22 | aoj_dsl_1_a, 23 | aoj_dsl_1_b, 24 | aoj_dsl_2_b, 25 | aoj_dsl_2_d, 26 | aoj_grl_1_a, 27 | aoj_grl_3_c, 28 | aoj_grl_6_a, 29 | yuki_1601, 30 | yuki_3287, 31 | } 32 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/aoj_0000.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use crate::test_set::{Aoj, Jury, Oj}; 4 | 5 | use scanner::Scanner; 6 | 7 | pub struct Aoj0000 {} 8 | 9 | impl Jury for Aoj0000 { 10 | type Input = (); 11 | type Output = Vec; 12 | const TL: Duration = Duration::from_millis(1000); 13 | const PROBLEM: Oj = Aoj("0000"); 14 | fn parse_input(_: String) -> Self::Input {} 15 | fn parse_output(_: &(), output: String) -> Self::Output { 16 | let mut output: Scanner = output.into(); 17 | 18 | output.next_n(81).unwrap() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/aoj_0002.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use crate::test_set::{Aoj, Jury, Oj}; 4 | 5 | use scanner::Scanner; 6 | 7 | pub struct Aoj0002 {} 8 | 9 | impl Jury for Aoj0002 { 10 | type Input = Vec<(u32, u32)>; 11 | type Output = Vec; 12 | const TL: Duration = Duration::from_millis(1000); 13 | const PROBLEM: Oj = Aoj("0002"); 14 | fn parse_input(input: String) -> Self::Input { 15 | let mut input: Scanner = input.into(); 16 | 17 | std::iter::repeat(0) 18 | .map(|_| input.next()) 19 | .take_while(std::result::Result::is_ok) 20 | .map(std::result::Result::unwrap) 21 | .collect() 22 | } 23 | fn parse_output(input: &Self::Input, output: String) -> Self::Output { 24 | let n = input.len(); 25 | let mut output: Scanner = output.into(); 26 | 27 | output.next_n(n).unwrap() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/aoj_0270.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use crate::test_set::{Aoj, Jury, Oj}; 4 | 5 | use scanner::Scanner; 6 | 7 | pub struct Aoj0270 {} 8 | 9 | impl Jury for Aoj0270 { 10 | type Input = (Vec, Vec); 11 | type Output = Vec; 12 | const TL: Duration = Duration::from_millis(3000); 13 | const PROBLEM: Oj = Aoj("0270"); 14 | fn parse_input(input: String) -> Self::Input { 15 | let mut input: Scanner = input.into(); 16 | 17 | let (n, q) = input.next().unwrap(); 18 | let c = input.next_n(n).unwrap(); 19 | let qs = input.next_n(q).unwrap(); 20 | (c, qs) 21 | } 22 | fn parse_output((_, qs): &Self::Input, output: String) -> Self::Output { 23 | let q = qs.len(); 24 | let mut output: Scanner = output.into(); 25 | 26 | output.next_n(q).unwrap() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/aoj_0564.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use crate::test_set::{Aoj, Jury, Oj}; 4 | 5 | use scanner::Scanner; 6 | 7 | pub struct Aoj0564 {} 8 | 9 | impl Jury for Aoj0564 { 10 | type Input = Vec<(u64, u64)>; 11 | type Output = u64; 12 | const TL: Duration = Duration::from_millis(8000); 13 | const PROBLEM: Oj = Aoj("0564"); 14 | fn parse_input(input: String) -> Self::Input { 15 | let mut input: Scanner = input.into(); 16 | 17 | let n = input.next().unwrap(); 18 | input.next_n(n).unwrap() 19 | } 20 | fn parse_output(_: &Self::Input, output: String) -> Self::Output { 21 | let mut output: Scanner = output.into(); 22 | 23 | output.next().unwrap() 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/aoj_0575.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use crate::test_set::{Aoj, Jury, Oj}; 4 | 5 | use scanner::Scanner; 6 | 7 | pub struct Aoj0575 {} 8 | 9 | impl Jury for Aoj0575 { 10 | type Input = ( 11 | usize, 12 | Vec<(usize, usize, i32)>, 13 | Vec, 14 | Vec<(usize, usize)>, 15 | ); 16 | type Output = Vec; 17 | const TL: Duration = Duration::from_millis(8000); 18 | const PROBLEM: Oj = Aoj("0575"); 19 | fn parse_input(input: String) -> Self::Input { 20 | let mut input: Scanner = input.into(); 21 | 22 | let (n, k, m, q) = input.next().unwrap(); 23 | let abl = (0..k).map(|_| { 24 | let a = input.next_m1().unwrap(); 25 | let b = input.next_m1().unwrap(); 26 | let l = input.next().unwrap(); 27 | (a, b, l) 28 | }); 29 | let abl = abl.collect(); 30 | let f = (0..m).map(|_| input.next_m1().unwrap()).collect(); 31 | let qs = (0..q).map(|_| { 32 | let s = input.next_m1().unwrap(); 33 | let t = input.next_m1().unwrap(); 34 | (s, t) 35 | }); 36 | let qs = qs.collect(); 37 | 38 | (n, abl, f, qs) 39 | } 40 | fn parse_output( 41 | (_, _, _, qs): &Self::Input, 42 | output: String, 43 | ) -> Self::Output { 44 | let mut output: Scanner = output.into(); 45 | let q = qs.len(); 46 | 47 | output.next_n(q).unwrap() 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/aoj_1180.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use crate::test_set::{Aoj, Jury, Oj}; 4 | 5 | use scanner::Scanner; 6 | 7 | pub struct Aoj1180 {} 8 | 9 | impl Jury for Aoj1180 { 10 | type Input = Vec<(u32, usize)>; 11 | type Output = Vec<(usize, u32, usize)>; 12 | const TL: Duration = Duration::from_millis(8000); 13 | const PROBLEM: Oj = Aoj("1180"); 14 | fn parse_input(input: String) -> Self::Input { 15 | let mut input: Scanner = input.into(); 16 | 17 | std::iter::successors(Some((1, 1)), |_| match input.next().unwrap() { 18 | (0, 0) => None, 19 | (a, l) => Some((a, l)), 20 | }) 21 | .skip(1) 22 | .collect() 23 | } 24 | fn parse_output(input: &Self::Input, output: String) -> Self::Output { 25 | let mut output: Scanner = output.into(); 26 | 27 | let n = input.len(); 28 | (0..n).map(|_| output.next().unwrap()).collect() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/aoj_2880.rs: -------------------------------------------------------------------------------- 1 | use std::ops::RangeInclusive; 2 | use std::time::Duration; 3 | 4 | use crate::test_set::{Aoj, Jury, Oj}; 5 | 6 | use scanner::Scanner; 7 | 8 | pub struct Aoj2880 {} 9 | 10 | impl Jury for Aoj2880 { 11 | type Input = ( 12 | u32, 13 | Vec<(u32, RangeInclusive)>, 14 | Vec<(u32, RangeInclusive)>, 15 | ); 16 | type Output = Vec; 17 | const TL: Duration = Duration::from_millis(2000); 18 | const PROBLEM: Oj = Aoj("2880"); 19 | fn parse_input(input: String) -> Self::Input { 20 | let mut input: Scanner = input.into(); 21 | 22 | let (n, m, q) = input.next().unwrap(); 23 | let dab = (0..m).map(|_| { 24 | let (d, a, b) = input.next().unwrap(); 25 | (d, a..=b) 26 | }); 27 | let dab = dab.collect(); 28 | let est = (0..q).map(|_| { 29 | let (e, s, t) = input.next().unwrap(); 30 | (e, s..=t) 31 | }); 32 | let est = est.collect(); 33 | 34 | (n, dab, est) 35 | } 36 | fn parse_output((_, _, qs): &Self::Input, output: String) -> Self::Output { 37 | let q = qs.len(); 38 | let mut output: Scanner = output.into(); 39 | 40 | (0..q) 41 | .map(|_| match output.get_line().trim() { 42 | "Yes" => true, 43 | "No" => false, 44 | _ => unreachable!(), 45 | }) 46 | .collect() 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/aoj_alds1_14_b.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use crate::test_set::{Aoj, Jury, Oj}; 4 | 5 | use scanner::Scanner; 6 | 7 | pub struct AojAldsOne14B {} 8 | 9 | impl Jury for AojAldsOne14B { 10 | type Input = (String, String); 11 | type Output = Vec; 12 | const TL: Duration = Duration::from_millis(1000); 13 | const PROBLEM: Oj = Aoj("ALDS1_14_B"); 14 | fn parse_input(input: String) -> Self::Input { 15 | let mut input: Scanner = input.into(); 16 | 17 | let t = input.next().unwrap(); 18 | let p = input.next().unwrap(); 19 | 20 | (t, p) 21 | } 22 | fn parse_output(_: &Self::Input, output: String) -> Self::Output { 23 | let mut output: Scanner = output.into(); 24 | 25 | (0..) 26 | .map(|_| output.next()) 27 | .take_while(std::result::Result::is_ok) 28 | .map(std::result::Result::unwrap) 29 | .collect() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/aoj_alds1_14_d.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use crate::test_set::{Aoj, Jury, Oj}; 4 | 5 | use scanner::Scanner; 6 | 7 | pub struct AojAldsOne14D {} 8 | 9 | impl Jury for AojAldsOne14D { 10 | type Input = (String, Vec); 11 | type Output = Vec; 12 | const TL: Duration = Duration::from_millis(3000); 13 | const PROBLEM: Oj = Aoj("ALDS1_14_D"); 14 | fn parse_input(input: String) -> Self::Input { 15 | let mut input: Scanner = input.into(); 16 | 17 | let t = input.next().unwrap(); 18 | let q = input.next().unwrap(); 19 | let p = input.next_n(q).unwrap(); 20 | 21 | (t, p) 22 | } 23 | fn parse_output((_, p): &Self::Input, output: String) -> Self::Output { 24 | let mut output: Scanner = output.into(); 25 | 26 | p.into_iter() 27 | .map(|_| match output.get_line().trim() { 28 | "0" => false, 29 | "1" => true, 30 | _ => unreachable!(), 31 | }) 32 | .collect() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/aoj_dsl_1_a.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use serde::{Deserialize, Serialize}; 4 | 5 | use crate::test_set::{Aoj, Jury, Oj}; 6 | 7 | use scanner::Scanner; 8 | 9 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)] 10 | pub enum Query { 11 | Unite(usize, usize), 12 | Same(usize, usize), 13 | } 14 | 15 | pub struct AojDsl1A {} 16 | 17 | impl Jury for AojDsl1A { 18 | type Input = (usize, Vec); 19 | type Output = Vec; 20 | const TL: Duration = Duration::from_millis(3000); 21 | const PROBLEM: Oj = Aoj("DSL_1_A"); 22 | fn parse_input(input: String) -> Self::Input { 23 | let mut input: Scanner = input.into(); 24 | 25 | let (n, q) = input.next().unwrap(); 26 | 27 | let qs = (0..q).map(|_| match input.next().unwrap() { 28 | 0 => { 29 | let (x, y) = input.next().unwrap(); 30 | Query::Unite(x, y) 31 | } 32 | 1 => { 33 | let (x, y) = input.next().unwrap(); 34 | Query::Same(x, y) 35 | } 36 | _ => unreachable!(), 37 | }); 38 | (n, qs.collect()) 39 | } 40 | fn parse_output((_n, qs): &Self::Input, output: String) -> Self::Output { 41 | let mut output: Scanner = output.into(); 42 | 43 | qs.iter() 44 | .filter_map(|q| match q { 45 | Query::Unite(_, _) => None, 46 | Query::Same(_, _) => Some(match output.next().unwrap() { 47 | 0 => false, 48 | 1 => true, 49 | _ => unreachable!(), 50 | }), 51 | }) 52 | .collect() 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/aoj_dsl_1_b.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use serde::{Deserialize, Serialize}; 4 | 5 | use crate::test_set::{Aoj, Jury, Oj}; 6 | 7 | use scanner::Scanner; 8 | 9 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)] 10 | pub enum Query { 11 | Relate(usize, usize, i32), 12 | Diff(usize, usize), 13 | } 14 | 15 | pub struct AojDsl1B {} 16 | 17 | impl Jury for AojDsl1B { 18 | type Input = (usize, Vec); 19 | type Output = Vec>; 20 | const TL: Duration = Duration::from_millis(3000); 21 | const PROBLEM: Oj = Aoj("DSL_1_B"); 22 | fn parse_input(input: String) -> Self::Input { 23 | let mut input: Scanner = input.into(); 24 | 25 | let (n, q) = input.next().unwrap(); 26 | 27 | let qs = (0..q).map(|_| match input.next().unwrap() { 28 | 0 => { 29 | let (x, y, z) = input.next().unwrap(); 30 | Query::Relate(x, y, z) 31 | } 32 | 1 => { 33 | let (x, y) = input.next().unwrap(); 34 | Query::Diff(x, y) 35 | } 36 | _ => unreachable!(), 37 | }); 38 | (n, qs.collect()) 39 | } 40 | fn parse_output((_n, qs): &Self::Input, output: String) -> Self::Output { 41 | let mut output: Scanner = output.into(); 42 | 43 | qs.iter() 44 | .filter_map(|q| match q { 45 | Query::Relate(_, _, _) => None, 46 | Query::Diff(_, _) => Some(match output.get_line().trim() { 47 | "?" => None, 48 | z => Some(z.parse().unwrap()), 49 | }), 50 | }) 51 | .collect() 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/aoj_dsl_2_b.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use serde::{Deserialize, Serialize}; 4 | 5 | use crate::test_set::{Aoj, Jury, Oj}; 6 | 7 | use scanner::Scanner; 8 | 9 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)] 10 | pub enum Query { 11 | Add(usize, u64), 12 | GetSum(usize, usize), 13 | } 14 | 15 | pub struct AojDsl2B {} 16 | 17 | impl Jury for AojDsl2B { 18 | type Input = (usize, Vec); 19 | type Output = Vec; 20 | const TL: Duration = Duration::from_millis(1000); 21 | const PROBLEM: Oj = Aoj("DSL_2_B"); 22 | fn parse_input(input: String) -> Self::Input { 23 | let mut input: Scanner = input.into(); 24 | 25 | let (n, q) = input.next().unwrap(); 26 | 27 | let qs = (0..q).map(|_| match input.next().unwrap() { 28 | 0 => { 29 | let i = input.next_m1().unwrap(); 30 | let x = input.next().unwrap(); 31 | Query::Add(i, x) 32 | } 33 | 1 => { 34 | let s = input.next_m1().unwrap(); 35 | let t = input.next().unwrap(); 36 | Query::GetSum(s, t) 37 | } 38 | _ => unreachable!(), 39 | }); 40 | (n, qs.collect()) 41 | } 42 | fn parse_output((_n, qs): &Self::Input, output: String) -> Self::Output { 43 | let mut output: Scanner = output.into(); 44 | 45 | qs.iter() 46 | .filter_map(|q| match q { 47 | Query::Add(_, _) => None, 48 | Query::GetSum(_, _) => Some(output.next().unwrap()), 49 | }) 50 | .collect() 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/aoj_dsl_2_d.rs: -------------------------------------------------------------------------------- 1 | use std::ops::Range; 2 | use std::time::Duration; 3 | 4 | use serde::{Deserialize, Serialize}; 5 | 6 | use crate::test_set::{judge_vec, Aoj, Jury, Oj, Verdict}; 7 | 8 | use scanner::Scanner; 9 | 10 | #[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)] 11 | pub enum Query { 12 | Update(Range, u32), 13 | Find(usize), 14 | } 15 | 16 | pub struct AojDsl2D {} 17 | 18 | impl Jury for AojDsl2D { 19 | type Input = (usize, Vec); 20 | type Output = Vec; 21 | const TL: Duration = Duration::from_millis(1000); 22 | const PROBLEM: Oj = Aoj("DSL_2_D"); 23 | fn parse_input(input: String) -> Self::Input { 24 | let mut input: Scanner = input.into(); 25 | 26 | let (n, q) = input.next().unwrap(); 27 | 28 | let qs = (0..q).map(|_| match input.next().unwrap() { 29 | 0 => { 30 | let s = input.next().unwrap(); 31 | let t = input.next::().unwrap() + 1; 32 | let x = input.next().unwrap(); 33 | Query::Update(s..t, x) 34 | } 35 | 1 => { 36 | let i = input.next().unwrap(); 37 | Query::Find(i) 38 | } 39 | _ => unreachable!(), 40 | }); 41 | (n, qs.collect()) 42 | } 43 | fn parse_output((_n, qs): &Self::Input, output: String) -> Self::Output { 44 | let mut output: Scanner = output.into(); 45 | 46 | qs.iter() 47 | .filter_map(|q| match q { 48 | Query::Update(_, _) => None, 49 | Query::Find(_) => Some(output.next().unwrap()), 50 | }) 51 | .collect() 52 | } 53 | fn judge( 54 | _: Self::Input, 55 | output: Self::Output, 56 | jury: Self::Output, 57 | ) -> Verdict { 58 | judge_vec(&output, &jury) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/aoj_grl_1_a.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use crate::test_set::{Aoj, Jury, Oj}; 4 | 5 | use scanner::Scanner; 6 | 7 | pub struct AojGrl1A {} 8 | 9 | impl Jury for AojGrl1A { 10 | type Input = (usize, usize, Vec<(usize, usize, i32)>); 11 | type Output = Vec>; 12 | const TL: Duration = Duration::from_millis(3000); 13 | const PROBLEM: Oj = Aoj("GRL_1_A"); 14 | fn parse_input(input: String) -> Self::Input { 15 | let mut input: Scanner = input.into(); 16 | 17 | let (n, m, r) = input.next().unwrap(); 18 | let es = input.next_n(m).unwrap(); 19 | (n, r, es) 20 | } 21 | fn parse_output(&(n, _, _): &Self::Input, output: String) -> Self::Output { 22 | let mut output: Scanner = output.into(); 23 | 24 | (0..n) 25 | .map(|_| match output.get_line().trim() { 26 | "INF" => None, 27 | s => Some(s.parse().unwrap()), 28 | }) 29 | .collect() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/aoj_grl_3_c.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use crate::test_set::{Aoj, Jury, Oj}; 4 | 5 | use scanner::Scanner; 6 | 7 | pub struct AojGrl3C {} 8 | 9 | impl Jury for AojGrl3C { 10 | type Input = (usize, Vec<(usize, usize)>, Vec<(usize, usize)>); 11 | type Output = Vec; 12 | const TL: Duration = Duration::from_millis(1000); 13 | const PROBLEM: Oj = Aoj("GRL_3_C"); 14 | fn parse_input(input: String) -> Self::Input { 15 | let mut input: Scanner = input.into(); 16 | 17 | let (n, m) = input.next().unwrap(); 18 | let es = input.next_n(m).unwrap(); 19 | 20 | let q = input.next().unwrap(); 21 | let qs = input.next_n(q).unwrap(); 22 | (n, es, qs) 23 | } 24 | fn parse_output((_, _, qs): &Self::Input, output: String) -> Self::Output { 25 | let mut output: Scanner = output.into(); 26 | let q = qs.len(); 27 | 28 | (0..q) 29 | .map(|_| match output.get_line().trim() { 30 | "0" => false, 31 | "1" => true, 32 | _ => unreachable!(), 33 | }) 34 | .collect() 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/aoj_grl_6_a.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use crate::test_set::{Aoj, Jury, Oj}; 4 | 5 | use scanner::Scanner; 6 | 7 | pub struct AojGrl6A {} 8 | 9 | impl Jury for AojGrl6A { 10 | type Input = (usize, Vec<(usize, usize, i32)>); 11 | type Output = i32; 12 | const TL: Duration = Duration::from_millis(1000); 13 | const PROBLEM: Oj = Aoj("GRL_6_A"); 14 | fn parse_input(input: String) -> Self::Input { 15 | let mut input: Scanner = input.into(); 16 | 17 | let (n, m) = input.next().unwrap(); 18 | let es = input.next_n(m).unwrap(); 19 | (n, es) 20 | } 21 | fn parse_output(_: &Self::Input, output: String) -> Self::Output { 22 | let mut output: Scanner = output.into(); 23 | output.next().unwrap() 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/template.rs: -------------------------------------------------------------------------------- 1 | use std::*; 2 | 3 | use crate::test_set::*; 4 | 5 | use serde::{Deserialize, Serialize}; 6 | 7 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)] 8 | pub enum Query { 9 | Type1(usize), 10 | Type2(usize), 11 | } 12 | 13 | pub struct Template {} 14 | 15 | impl Jury for Template { 16 | type Input = TemplateInput; 17 | type Output = TemplateOutput; 18 | const TL: Duration = Duration::from_millis(TEMPLATE); 19 | const PROBLEM: Oj = Template("Template"); 20 | fn parse_input(input: String) -> Self::Input { 21 | let mut input = input.lines(); 22 | } 23 | fn parse_output(_: &Self::Input, output: String) -> Self::Output { 24 | let mut output = output.lines(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/yuki_1601.rs: -------------------------------------------------------------------------------- 1 | use std::ops::RangeInclusive; 2 | use std::time::Duration; 3 | 4 | use crate::test_set::{Jury, Oj, Yukicoder}; 5 | 6 | use scanner::Scanner; 7 | 8 | pub struct Yuki1601 {} 9 | 10 | impl Jury for Yuki1601 { 11 | type Input = (u64, Vec>); 12 | type Output = Vec; 13 | const TL: Duration = Duration::from_millis(2000); 14 | const PROBLEM: Oj = Yukicoder("1601"); 15 | fn parse_input(input: String) -> Self::Input { 16 | let mut input: Scanner = input.into(); 17 | 18 | let (d, q) = input.next().unwrap(); 19 | 20 | let ab = (0..q).map(|_| { 21 | let (a, b) = input.next().unwrap(); 22 | a..=b 23 | }); 24 | let ab = ab.collect(); 25 | 26 | (d, ab) 27 | } 28 | fn parse_output((_, qs): &Self::Input, output: String) -> Self::Output { 29 | let q = qs.len(); 30 | let mut output: Scanner = output.into(); 31 | 32 | output.next_n(q).unwrap() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /verifiers/verify/src/jury/yuki_3287.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use serde::{Deserialize, Serialize}; 4 | 5 | use crate::test_set::{Jury, Oj, Yukicoder}; 6 | 7 | use scanner::Scanner; 8 | 9 | pub struct Yuki3287 {} 10 | 11 | #[derive(Clone, Copy, Eq, PartialEq, Deserialize, Serialize)] 12 | pub enum Query { 13 | Type1(usize, usize), 14 | } 15 | 16 | impl Jury for Yuki3287 { 17 | type Input = (Vec, Vec); 18 | type Output = Vec; 19 | const TL: Duration = Duration::from_millis(2000); 20 | const PROBLEM: Oj = Yukicoder("3287"); 21 | fn parse_input(input: String) -> Self::Input { 22 | let mut input: Scanner = input.into(); 23 | 24 | let (n, q) = input.next().unwrap(); 25 | 26 | let a = input.next_n(n).unwrap(); 27 | let qs = (0..q).map(|_| match input.next().unwrap() { 28 | 1 => { 29 | let l = input.next_m1().unwrap(); 30 | let r = input.next().unwrap(); 31 | Query::Type1(l, r) 32 | } 33 | _ => unreachable!(), 34 | }); 35 | let qs = qs.collect(); 36 | 37 | (a, qs) 38 | } 39 | fn parse_output((_, qs): &Self::Input, output: String) -> Self::Output { 40 | let q = qs.len(); 41 | let mut output: Scanner = output.into(); 42 | 43 | output.next_n(q).unwrap() 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /verifiers/verify/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod jury; 2 | pub mod solver; 3 | pub mod test_set; 4 | #[doc(inline)] 5 | pub use test_set::*; 6 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver.rs: -------------------------------------------------------------------------------- 1 | macro_rules! uses { 2 | ( $( $i:ident, )* ) => { 3 | $( 4 | pub mod $i; 5 | #[doc(inline)] 6 | pub use $i::*; 7 | )* 8 | } 9 | } 10 | 11 | uses! { 12 | aoj_0000, 13 | aoj_0000_wa, 14 | aoj_0000_re, 15 | aoj_0000_tle, 16 | aoj_0002, 17 | aoj_0270, 18 | aoj_0425, 19 | aoj_0564, 20 | aoj_0575, 21 | aoj_1180, 22 | aoj_2880, 23 | aoj_alds1_14_b, 24 | aoj_alds1_14_b_kmp, 25 | aoj_alds1_14_b_z, 26 | aoj_alds1_14_d, 27 | aoj_dsl_1_a, 28 | aoj_dsl_1_b, 29 | aoj_dsl_2_b, 30 | aoj_dsl_2_d_iset, 31 | aoj_grl_1_a, 32 | aoj_grl_3_c, 33 | aoj_grl_6_a, 34 | yuki_1601, 35 | yuki_3287, 36 | } 37 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_0000.rs: -------------------------------------------------------------------------------- 1 | use crate::jury; 2 | use crate::test_set::Solver; 3 | 4 | pub struct Aoj0000 {} 5 | 6 | impl Solver for Aoj0000 { 7 | type Jury = jury::Aoj0000; 8 | fn solve(_: ()) -> Vec { 9 | (1..=9) 10 | .flat_map(|i| { 11 | (1..=9).map(move |j| format!("{}x{}={}", i, j, i * j)) 12 | }) 13 | .collect::>() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_0000_re.rs: -------------------------------------------------------------------------------- 1 | use crate::jury; 2 | use crate::test_set::Solver; 3 | 4 | pub struct Aoj0000Re {} 5 | 6 | impl Solver for Aoj0000Re { 7 | type Jury = jury::Aoj0000; 8 | fn solve(_: ()) -> Vec { 9 | panic!("nekochan"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_0000_tle.rs: -------------------------------------------------------------------------------- 1 | use crate::jury; 2 | use crate::test_set::Solver; 3 | 4 | pub struct Aoj0000Tle {} 5 | 6 | impl Solver for Aoj0000Tle { 7 | type Jury = jury::Aoj0000; 8 | fn solve(_: ()) -> Vec { 9 | let n = 100_000_000; 10 | vec![(1..=n) 11 | .map(|i| (1..=i).step_by(2).sum::()) 12 | .sum::() 13 | .to_string()] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_0000_wa.rs: -------------------------------------------------------------------------------- 1 | use crate::jury; 2 | use crate::test_set::Solver; 3 | 4 | pub struct Aoj0000Wa {} 5 | 6 | impl Solver for Aoj0000Wa { 7 | type Jury = jury::Aoj0000; 8 | fn solve(_: ()) -> Vec { 9 | vec!["hello world".to_string()] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_0002.rs: -------------------------------------------------------------------------------- 1 | use crate::jury; 2 | use crate::test_set::Solver; 3 | 4 | pub struct Aoj0002 {} 5 | 6 | impl Solver for Aoj0002 { 7 | type Jury = jury::Aoj0002; 8 | fn solve(input: Vec<(u32, u32)>) -> Vec { 9 | input 10 | .into_iter() 11 | .map(|(a, b)| (a + b).to_string().len()) 12 | .collect() 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_0270.rs: -------------------------------------------------------------------------------- 1 | use bisect_::bisect_slice; 2 | 3 | use crate::jury; 4 | use crate::test_set::Solver; 5 | 6 | pub struct Aoj0270 {} 7 | 8 | impl Solver for Aoj0270 { 9 | type Jury = jury::Aoj0270; 10 | fn solve((mut c, qs): (Vec, Vec)) -> Vec { 11 | c.push(0); 12 | c.sort_unstable(); 13 | let c = c; 14 | let n = c.len(); 15 | 16 | qs.into_iter() 17 | .map(|q| { 18 | let mut res = c[n - 1] % q; 19 | for i in 1.. { 20 | let y = i * q; 21 | let pred = |&x: &u32| x < y; 22 | let b = bisect_slice(&c, pred); 23 | if b == n { 24 | break; 25 | } 26 | res = res.max(c[b - 1] % q); 27 | } 28 | res 29 | }) 30 | .collect() 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_0564.rs: -------------------------------------------------------------------------------- 1 | use std::marker::PhantomData; 2 | use std::ops::{Add, Range}; 3 | 4 | use serde::{Deserialize, Serialize}; 5 | 6 | use additive::{AddAssoc, Zero}; 7 | use fold::Fold; 8 | use fold_bisect::FoldBisect; 9 | use op_add::OpAdd; 10 | use set_value::SetValue; 11 | 12 | use crate::jury; 13 | use crate::test_set::Solver; 14 | 15 | #[derive(Clone, Copy, Eq, PartialEq, Deserialize, Serialize)] 16 | pub struct Pair(u64, u64); 17 | 18 | impl Add for Pair { 19 | type Output = Self; 20 | fn add(self, other: Self) -> Self { 21 | Self(self.0 + other.0, self.1 + other.1) 22 | } 23 | } 24 | impl Zero for Pair { 25 | fn zero() -> Self { 26 | Self(0, 0) 27 | } 28 | } 29 | impl AddAssoc for Pair {} 30 | 31 | pub struct Aoj0564 { 32 | _d: PhantomData, 33 | } 34 | 35 | impl Solver for Aoj0564 36 | where 37 | D: From> 38 | + Fold, Output = OpAdd> 39 | + SetValue 40 | + FoldBisect, 41 | { 42 | type Jury = jury::Aoj0564; 43 | fn solve(mut ab: Vec<(u64, u64)>) -> u64 { 44 | let n = ab.len(); 45 | 46 | ab.sort_unstable(); 47 | let mut ab: Vec<_> = ab 48 | .into_iter() 49 | .enumerate() 50 | .map(|(i, (a, b))| (a, b, i)) 51 | .collect(); 52 | 53 | ab.sort_unstable_by(|x, y| y.1.cmp(&x.1)); 54 | let ab = ab; 55 | 56 | let mut res = 0; 57 | let mut dp: D = vec![Pair(0, 0); n].into(); 58 | for (a, b, i) in ab { 59 | let pred = |&Pair(a, k): &Pair| a <= b * k; 60 | dp.set_value(i, Pair(a, 1)); 61 | let ir = dp.fold_bisect(0, pred).0; 62 | res = res.max(dp.fold(0..ir).1); 63 | } 64 | 65 | res 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_1180.rs: -------------------------------------------------------------------------------- 1 | use tortoise_hare::cycle_mu_lambda; 2 | 3 | use crate::jury; 4 | use crate::test_set::Solver; 5 | 6 | pub struct Aoj1180 {} 7 | 8 | impl Solver for Aoj1180 { 9 | type Jury = jury::Aoj1180; 10 | fn solve(al: Vec<(u32, usize)>) -> Vec<(usize, u32, usize)> { 11 | al.into_iter() 12 | .map(|(a, l)| { 13 | let f = |a| { 14 | let s = format!("{0:01$}", a, l); 15 | let mut s: Vec<_> = s.chars().collect(); 16 | s.sort_unstable(); 17 | let s0: u32 = s.iter().collect::().parse().unwrap(); 18 | let s1: u32 = 19 | s.iter().rev().collect::().parse().unwrap(); 20 | s1 - s0 21 | }; 22 | let (mu, lambda) = cycle_mu_lambda(a, f); 23 | let a = std::iter::successors(Some(a), |&x| Some(f(x))) 24 | .nth(mu) 25 | .unwrap(); 26 | (mu, a, lambda) 27 | }) 28 | .collect() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_2880.rs: -------------------------------------------------------------------------------- 1 | use std::ops::RangeInclusive; 2 | 3 | use crate::jury; 4 | use crate::test_set::Solver; 5 | 6 | use interval_set::IntervalSet; 7 | 8 | pub struct Aoj2880 {} 9 | 10 | impl Solver for Aoj2880 { 11 | type Jury = jury::Aoj2880; 12 | fn solve( 13 | (_n, dab, est): ( 14 | u32, 15 | Vec<(u32, RangeInclusive)>, 16 | Vec<(u32, RangeInclusive)>, 17 | ), 18 | ) -> Vec { 19 | let q = est.len(); 20 | 21 | // (day, qi, range) 22 | let dab = dab 23 | .into_iter() 24 | .map(|(d, ab)| ((d, 1), 0, (*ab.start(), *ab.end()))); 25 | let est = est 26 | .into_iter() 27 | .enumerate() 28 | .map(|(i, (e, st))| ((e, 0), i, (*st.start(), *st.end()))); 29 | let mut qs: Vec<_> = dab.chain(est).collect(); 30 | qs.sort_unstable(); 31 | 32 | let mut is = IntervalSet::::new(); 33 | let mut res = vec![false; q]; 34 | 35 | for ((_, d), qi, (rs, re)) in qs { 36 | match d { 37 | 0 => res[qi] = rs >= re || is.has_range(&(rs..=re)), 38 | 1 => is.insert(rs..=re), 39 | _ => unreachable!(), 40 | } 41 | } 42 | res 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_alds1_14_b.rs: -------------------------------------------------------------------------------- 1 | use crate::jury; 2 | use crate::test_set::Solver; 3 | 4 | use suffix_array::SuffixArray; 5 | 6 | pub struct AojAldsOne14B {} 7 | 8 | impl Solver for AojAldsOne14B { 9 | type Jury = jury::AojAldsOne14B; 10 | fn solve((t, p): (String, String)) -> Vec { 11 | let sa: SuffixArray<_> = t.into(); 12 | let mut res: Vec<_> = sa.search_str(&p).collect(); 13 | res.sort_unstable(); 14 | res 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_alds1_14_b_kmp.rs: -------------------------------------------------------------------------------- 1 | use crate::jury; 2 | use crate::test_set::Solver; 3 | 4 | use kmp::KmpSearcher; 5 | 6 | pub struct AojAldsOne14BKmp {} 7 | 8 | impl Solver for AojAldsOne14BKmp { 9 | type Jury = jury::AojAldsOne14B; 10 | fn solve((t, p): (String, String)) -> Vec { 11 | let t: Vec<_> = t.as_str().bytes().collect(); 12 | let p: Vec<_> = p.as_str().bytes().collect(); 13 | let pat: KmpSearcher = p.into(); 14 | pat.occurrences(&t).into_iter().map(|r| r.start).collect() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_alds1_14_b_z.rs: -------------------------------------------------------------------------------- 1 | use crate::jury; 2 | use crate::test_set::Solver; 3 | 4 | use z_algo::ZSearcher; 5 | 6 | pub struct AojAldsOne14BZ {} 7 | 8 | impl Solver for AojAldsOne14BZ { 9 | type Jury = jury::AojAldsOne14B; 10 | fn solve((t, p): (String, String)) -> Vec { 11 | let t: Vec<_> = t.as_str().bytes().collect(); 12 | let p: Vec<_> = p.as_str().bytes().collect(); 13 | let pat: ZSearcher = p.into(); 14 | pat.occurrences(&t).into_iter().map(|r| r.start).collect() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_alds1_14_d.rs: -------------------------------------------------------------------------------- 1 | use crate::jury; 2 | use crate::test_set::Solver; 3 | 4 | use suffix_array::SuffixArray; 5 | 6 | pub struct AojAldsOne14D {} 7 | 8 | impl Solver for AojAldsOne14D { 9 | type Jury = jury::AojAldsOne14D; 10 | fn solve((t, p): (String, Vec)) -> Vec { 11 | let sa: SuffixArray<_> = t.into(); 12 | p.into_iter() 13 | .map(|p| sa.search_str(&p).next().is_some()) 14 | .collect() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_dsl_1_a.rs: -------------------------------------------------------------------------------- 1 | use std::marker::PhantomData; 2 | 3 | use crate::jury; 4 | use crate::test_set::Solver; 5 | 6 | use disjoint_set::DisjointSet; 7 | 8 | use jury::aoj_dsl_1_a::Query; 9 | 10 | pub struct AojDsl1A { 11 | _d: PhantomData, 12 | } 13 | 14 | impl Solver for AojDsl1A 15 | where 16 | D: DisjointSet, 17 | { 18 | type Jury = jury::AojDsl1A; 19 | fn solve((n, qs): (usize, Vec)) -> Vec { 20 | let mut ds = D::new(n); 21 | qs.into_iter() 22 | .filter_map(|q| match q { 23 | Query::Unite(x, y) => { 24 | ds.unite(x, y); 25 | None 26 | } 27 | Query::Same(x, y) => Some(ds.equiv(x, y)), 28 | }) 29 | .collect() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_dsl_1_b.rs: -------------------------------------------------------------------------------- 1 | use std::marker::PhantomData; 2 | 3 | use crate::jury; 4 | use crate::test_set::Solver; 5 | 6 | use op_add::OpAdd; 7 | use potential_function::PotentialFunction; 8 | 9 | use jury::aoj_dsl_1_b::Query; 10 | 11 | pub struct AojDsl1B { 12 | _d: PhantomData, 13 | } 14 | 15 | impl Solver for AojDsl1B 16 | where 17 | D: PotentialFunction>, 18 | { 19 | type Jury = jury::AojDsl1B; 20 | fn solve((n, qs): (usize, Vec)) -> Vec> { 21 | let mut ds = D::new(n, OpAdd::::default()); 22 | qs.into_iter() 23 | .filter_map(|q| match q { 24 | Query::Relate(u, v, w) => { 25 | ds.relate(v, u, w); 26 | None 27 | } 28 | Query::Diff(u, v) => Some(ds.diff(v, u)), 29 | }) 30 | .collect() 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_dsl_2_b.rs: -------------------------------------------------------------------------------- 1 | use std::marker::PhantomData; 2 | use std::ops::{Index, Range}; 3 | 4 | use crate::jury; 5 | use crate::test_set::Solver; 6 | 7 | use jury::aoj_dsl_2_b::Query; 8 | 9 | use fold::Fold; 10 | use op_add::OpAdd; 11 | use set_value::SetValue; 12 | 13 | pub struct AojDsl2B { 14 | _d: PhantomData, 15 | } 16 | 17 | impl Solver for AojDsl2B 18 | where 19 | D: From> 20 | + SetValue 21 | + Index 22 | + Fold, Output = OpAdd>, 23 | { 24 | type Jury = jury::AojDsl2B; 25 | fn solve((n, qs): (usize, Vec)) -> Vec { 26 | let mut rq: D = vec![0_u64; n].into(); 27 | qs.into_iter() 28 | .filter_map(|q| match q { 29 | Query::Add(i, x) => { 30 | rq.set_value(i, rq[i] + x); 31 | None 32 | } 33 | Query::GetSum(s, t) => Some(rq.fold(s..t)), 34 | }) 35 | .collect() 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_dsl_2_d_iset.rs: -------------------------------------------------------------------------------- 1 | use std::ops::Range; 2 | 3 | use crate::jury; 4 | use crate::test_set::Solver; 5 | 6 | use jury::aoj_dsl_2_d::Query; 7 | 8 | use interval_set::IntervalSet; 9 | 10 | pub struct AojDsl2DIset {} 11 | 12 | impl Solver for AojDsl2DIset { 13 | type Jury = jury::AojDsl2D; 14 | fn solve((n, qs): (usize, Vec)) -> Vec { 15 | let w = 31; 16 | let mut iset = vec![IntervalSet::::new(); w]; 17 | 18 | for wi in 0..w { 19 | iset[wi].insert(0..n); 20 | } 21 | 22 | qs.into_iter() 23 | .filter_map(|q| match q { 24 | Query::Update(Range { start: s, end: t }, x) => { 25 | // eprintln!("update {:?} to {}", s..t, x); 26 | for wi in 0..w { 27 | if x >> wi & 1 == 0 { 28 | iset[wi].remove(s..t); 29 | } else { 30 | iset[wi].insert(s..t); 31 | } 32 | } 33 | None 34 | } 35 | Query::Find(i) => { 36 | // eprintln!("what value of [{}]", i); 37 | let res = (0..w) 38 | .filter_map(|wi| { 39 | if !iset[wi].is_empty() { 40 | // eprintln!("iset[{}]: {:#?}", wi, iset[wi]); 41 | } 42 | if iset[wi].has_range(&(i..=i)) { 43 | // eprintln!("has 2 ^ {}", wi); 44 | Some(1_u32 << wi) 45 | } else { 46 | None 47 | } 48 | }) 49 | .sum::(); 50 | Some(res) 51 | } 52 | }) 53 | .collect() 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_grl_1_a.rs: -------------------------------------------------------------------------------- 1 | use crate::jury; 2 | use crate::test_set::{Jury, Solver}; 3 | 4 | use dijkstra_::dijkstra; 5 | 6 | pub struct AojGrl1A {} 7 | 8 | impl Solver for AojGrl1A { 9 | type Jury = jury::AojGrl1A; 10 | fn solve((n, r, es): ::Input) -> Vec> { 11 | let g = { 12 | let mut g: Vec<_> = vec![vec![]; n]; 13 | for (u, v, w) in es { 14 | g[u].push((v, w)); 15 | } 16 | g 17 | }; 18 | 19 | let index = |&i: &usize| -> usize { i }; 20 | let delta = |&v: &usize| g[v].iter().cloned(); 21 | dijkstra(n, r, 0, index, delta) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_grl_3_c.rs: -------------------------------------------------------------------------------- 1 | use crate::jury; 2 | use crate::test_set::{Jury, Solver}; 3 | 4 | use scc_::scc; 5 | 6 | pub struct AojGrl3C {} 7 | 8 | impl Solver for AojGrl3C { 9 | type Jury = jury::AojGrl3C; 10 | fn solve((n, es, qs): ::Input) -> Vec { 11 | let g = { 12 | let mut g: Vec<_> = vec![vec![]; n]; 13 | for (u, v) in es { 14 | g[u].push(v); 15 | } 16 | g 17 | }; 18 | 19 | let index = |&i: &usize| -> usize { i }; 20 | let delta = |&v: &usize| g[v].iter().cloned(); 21 | let scc_id = scc(n, 0..n, index, delta); 22 | qs.into_iter() 23 | .map(|(u, v)| scc_id[u] == scc_id[v]) 24 | .collect() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/aoj_grl_6_a.rs: -------------------------------------------------------------------------------- 1 | use std::cell::RefCell; 2 | use std::rc::Rc; 3 | 4 | use crate::jury; 5 | use crate::test_set::{Jury, Solver}; 6 | 7 | use dinic_::dinic; 8 | 9 | pub struct AojGrl6A {} 10 | 11 | impl Solver for AojGrl6A { 12 | type Jury = jury::AojGrl6A; 13 | fn solve((n, es): ::Input) -> i32 { 14 | let g = { 15 | let mut g = vec![vec![]; n]; 16 | for (from, to, capacity) in es { 17 | let from_len = g[from].len(); 18 | let to_len = g[to].len(); 19 | g[from].push((to, Rc::new(RefCell::new(capacity)), to_len)); 20 | g[to].push((from, Rc::new(RefCell::new(0)), from_len)); 21 | } 22 | g 23 | }; 24 | 25 | let index = |&v: &usize| -> usize { v }; 26 | let delta = 27 | |&v: &usize| g[v].iter().map(|&(nv, ref w, r)| (nv, w.clone(), r)); 28 | let rev = |&nv: &usize, &r: &usize| g[nv][r].1.clone(); 29 | 30 | let s = 0; 31 | let t = n - 1; 32 | dinic(n, s, t, 0..n, 0, index, delta, rev) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/template.rs: -------------------------------------------------------------------------------- 1 | use std::*; 2 | 3 | use crate::jury; 4 | use crate::test_set::solver; 5 | 6 | use jury::template::*; 7 | 8 | use my_modules::*; 9 | 10 | pub struct Template {} 11 | 12 | impl Solver for Template { 13 | type Jury = jury::Template; 14 | fn solve(input: Self::Jury::Input) -> Self::Jury::Output {} 15 | } 16 | 17 | pub struct NekoTemplate {} 18 | 19 | impl NekoTemplate {} 20 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/yuki_1601.rs: -------------------------------------------------------------------------------- 1 | use std::ops::Bound::{Excluded, Included}; 2 | use std::ops::RangeInclusive; 3 | 4 | use interval_set::IntervalSet; 5 | 6 | use crate::jury; 7 | use crate::test_set::Solver; 8 | 9 | pub struct Yuki1601 {} 10 | 11 | impl Solver for Yuki1601 { 12 | type Jury = jury::Yuki1601; 13 | fn solve((_d, qs): (u64, Vec>)) -> Vec { 14 | let mut is = IntervalSet::::new(); 15 | let mut res = 0; 16 | qs.into_iter() 17 | .map(|q| { 18 | let (s, e) = q.into_inner(); 19 | is.insert(s..e + 1); 20 | res = match is.covering(&(s..=s)) { 21 | Some((Included(s), Excluded(e))) => res.max(e - s), 22 | _ => unreachable!(), 23 | }; 24 | res 25 | }) 26 | .collect() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /verifiers/verify/src/solver/yuki_3287.rs: -------------------------------------------------------------------------------- 1 | use std::marker::PhantomData; 2 | use std::ops::{Index, Range}; 3 | 4 | use fold::Fold; 5 | use fold_bisect::FoldBisectRev; 6 | use op_add::OpAdd; 7 | use op_max::OpMax; 8 | use set_value::SetValue; 9 | 10 | use crate::jury; 11 | use crate::test_set::Solver; 12 | 13 | use jury::yuki_3287::Query; 14 | 15 | pub struct Yuki3287 { 16 | _d1: PhantomData, 17 | _d2: PhantomData, 18 | } 19 | 20 | impl Solver for Yuki3287 21 | where 22 | D1: From> 23 | + Index 24 | + Fold, Output = OpMax> 25 | + FoldBisectRev, 26 | D2: From> 27 | + SetValue 28 | + Fold, Output = OpAdd>, 29 | { 30 | type Jury = jury::Yuki3287; 31 | fn solve((a, qs): (Vec, Vec)) -> Vec { 32 | #![allow(clippy::similar_names)] 33 | let n = a.len(); 34 | let q = qs.len(); 35 | 36 | let top: Vec<_> = { 37 | let rq: D1 = a.into(); 38 | (0..n) 39 | .map(|i| rq.fold_bisect_rev(i + 1, |x| x <= &rq[i]).0) 40 | .collect() 41 | }; 42 | 43 | let js = { 44 | let mut tmp = vec![vec![]; n]; 45 | for i in 0..n { 46 | tmp[top[i]].push(i); 47 | } 48 | tmp 49 | }; 50 | 51 | let qs = { 52 | let mut tmp = vec![vec![]; n]; 53 | for (iq, q) in qs.into_iter().enumerate() { 54 | match q { 55 | Query::Type1(l, r) => tmp[l].push(((l, r), iq)), 56 | } 57 | } 58 | tmp 59 | }; 60 | 61 | let mut rq: D2 = vec![0; n].into(); 62 | let mut res = vec![0; q]; 63 | 64 | for i in 0..n { 65 | for &j in &js[i] { 66 | rq.set_value(j, 1); 67 | } 68 | for &((l, r), iq) in &qs[i] { 69 | res[iq] = rq.fold(l..r); 70 | } 71 | } 72 | 73 | res 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /verifiers/verify/tests/test_judge.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod test_judge { 3 | use verify::solver::*; 4 | use verify::test_set::verify; 5 | 6 | #[test] 7 | fn test_ac() { 8 | verify::(); 9 | } 10 | 11 | #[test] 12 | #[should_panic(expected = "WA")] 13 | fn test_wa() { 14 | verify::(); 15 | } 16 | 17 | #[test] 18 | #[should_panic(expected = "RE")] 19 | fn test_re() { 20 | verify::(); 21 | } 22 | 23 | #[test] 24 | #[should_panic(expected = "TLE")] 25 | fn test_tle() { 26 | verify::(); 27 | } 28 | 29 | #[test] 30 | #[should_panic(expected = "no cases")] 31 | fn test_no() { 32 | verify::(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /verifiers/verify/tests/verify.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod verify { 3 | use verify::solver::*; 4 | use verify::test_set::verify; 5 | 6 | use op_add::OpAdd; 7 | use potentialized_union_find::PotentializedUnionFind; 8 | use union_find::UnionFind; 9 | 10 | #[test] 11 | fn verify_bisect() { 12 | verify::(); 13 | } 14 | 15 | #[test] 16 | fn verify_tortoise_hare() { 17 | verify::(); 18 | } 19 | 20 | #[test] 21 | fn verify_union_find() { 22 | verify::>(); 23 | } 24 | 25 | #[test] 26 | fn verify_mo() { 27 | verify::>(); 28 | } 29 | 30 | #[test] 31 | fn verify_dijkstra() { 32 | verify::(); 33 | } 34 | 35 | #[test] 36 | fn verify_parallel_bisect() { 37 | verify::>(); 38 | } 39 | 40 | #[test] 41 | fn verify_scc() { 42 | verify::(); 43 | } 44 | 45 | #[test] 46 | fn verify_dinic() { 47 | verify::(); 48 | } 49 | 50 | #[test] 51 | fn verify_kmp() { 52 | verify::(); 53 | } 54 | 55 | #[test] 56 | fn verify_z() { 57 | verify::(); 58 | } 59 | 60 | #[test] 61 | fn verify_potentialized_uf() { 62 | verify::>>>(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /verifiers/verify/tests/verify_interval_set.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod verify_interval_set { 3 | use verify::solver::*; 4 | use verify::test_set::verify; 5 | 6 | #[test] 7 | fn verify_with_aoj_2880() { 8 | verify::(); 9 | } 10 | 11 | #[test] 12 | fn verify_with_aoj_dsl_2_d_iset() { 13 | verify::(); 14 | } 15 | 16 | #[test] 17 | fn verify_yuki_1601() { 18 | verify::(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /verifiers/verify/tests/verify_suffix_array.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod verify_suffix_array { 3 | use verify::solver::*; 4 | use verify::test_set::verify; 5 | 6 | #[test] 7 | fn verify_with_aoj_alds1_14_b() { 8 | verify::(); 9 | } 10 | 11 | #[test] 12 | fn verify_with_aoj_alds1_14_d() { 13 | verify::(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /verifiers/verify/tests/verify_vec_segtree.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod verify_vec_segtree { 3 | use verify::solver::*; 4 | use verify::test_set::verify; 5 | 6 | use vec_segtree::*; 7 | 8 | #[test] 9 | fn verify_with_aoj_0564() { 10 | verify::>>(); 11 | } 12 | 13 | #[test] 14 | fn verify_with_aoj_dsl_1_2_b() { 15 | verify::>>(); 16 | } 17 | 18 | #[test] 19 | fn verify_yuki_3287() { 20 | verify::, VecSegtree<_>>>(); 21 | } 22 | } 23 | --------------------------------------------------------------------------------