From 3a2e480462c2be6586c73779ff4ba4fcda183790 Mon Sep 17 00:00:00 2001 From: Tifa <62847935+Tiphereth-A@users.noreply.github.com> Date: Tue, 25 Feb 2025 17:53:59 +0800 Subject: [PATCH] refactor: simplify, better v_bcc & e_bcc --- Makefile | 2 +- config.yml | 19 +- src/code/conv/conv_subset.hpp | 2 +- src/code/conv/conv_u64.hpp | 16 +- src/code/conv/fft_r2.hpp | 2 +- src/code/conv/fft_r3.hpp | 2 +- src/code/conv/ntt_doubling.hpp | 2 +- src/code/ds/d_ary_heap.hpp | 8 + src/code/ds/depq.hpp | 10 + src/code/ds/lichao_segtree.hpp | 2 +- src/code/ds/radix_heap.hpp | 4 +- src/code/ds/segtree.hpp | 2 +- src/code/ds/st_array.hpp | 2 +- src/code/edh/base64.hpp | 2 +- src/code/edh/bwt_inv.hpp | 2 +- src/code/edh/discretization.hpp | 12 +- src/code/{util => edh}/garsia_wachs.hpp | 6 +- src/code/edh/hash_splitmix64.hpp | 4 +- src/code/fast/rsort32.hpp | 9 +- src/code/game/npuzzle_data.hpp | 3 +- src/code/game/sudoku.hpp | 4 +- src/code/geo2d/any_ins_ss.hpp | 2 +- src/code/geo2d/argsort.hpp | 2 +- src/code/geo2d/aunion_cs.hpp | 5 +- src/code/geo2d/aunion_pos.hpp | 4 +- src/code/geo2d/circle.hpp | 5 +- src/code/geo2d/cvh.hpp | 4 +- src/code/geo2d/dcvh.hpp | 4 +- src/code/geo2d/femwebp.hpp | 2 +- src/code/geo2d/max_cover_ps.hpp | 2 +- src/code/geo2d/maxv_cvh_cnt.hpp | 5 +- src/code/geo2d/min_dis_ps.hpp | 2 +- src/code/geo2d/point.hpp | 2 +- src/code/geo2d/polygon.hpp | 2 +- src/code/geo3d/cvh3d.hpp | 5 +- src/code/geo3d/point3d.hpp | 2 +- src/code/graph/alist.hpp | 12 ++ src/code/graph/alists.hpp | 8 + src/code/graph/blossomw.hpp | 8 +- src/code/graph/bm.hpp | 7 +- src/code/graph/chordal.hpp | 12 +- src/code/graph/chrom_num.hpp | 2 +- src/code/graph/dijkstra.hpp | 2 +- src/code/graph/domtree.hpp | 2 +- src/code/graph/e_bcc.hpp | 53 ++--- src/code/graph/eog.hpp | 21 +- src/code/graph/euler_trail.hpp | 4 +- src/code/graph/find_cycle.hpp | 4 +- src/code/graph/johnson.hpp | 4 +- src/code/graph/kosaraju.hpp | 2 +- src/code/graph/make_alistr.hpp | 4 +- src/code/graph/manhattan_mst.hpp | 2 +- src/code/graph/min_cycle_mean.hpp | 12 +- src/code/graph/path.hpp | 4 +- src/code/graph/ringcnt4.hpp | 4 +- src/code/graph/ringenum3.hpp | 2 +- src/code/graph/sat2.hpp | 4 +- src/code/graph/steiner_tree.hpp | 2 +- src/code/graph/topo_sort.hpp | 4 +- src/code/graph/v_bcc.hpp | 80 ++++--- src/code/io/fastin.hpp | 2 +- src/code/io/fastout.hpp | 8 +- src/code/lalg/det_rd_mat.hpp | 2 +- src/code/lalg/ge_bmat.hpp | 2 +- src/code/lalg/ge_mat.hpp | 4 +- src/code/lalg/mat.hpp | 4 +- src/code/lalg/matsp.hpp | 8 +- src/code/lalg/minpoly_rd_mat.hpp | 4 +- src/code/math/berlekamp_massey.hpp | 2 +- src/code/math/fact_helper.hpp | 2 +- src/code/math/fact_mint.hpp | 2 +- src/code/math/factl_helper.hpp | 2 +- src/code/math/isqrt.hpp | 2 + src/code/{util => math}/josephus.hpp | 7 +- src/code/math/mint.hpp | 2 +- src/code/math/mpi.hpp | 203 +++++++++--------- src/code/math/youngt.hpp | 2 +- src/code/nt/exgcd.hpp | 2 +- src/code/nt/lcm.hpp | 2 +- src/code/nt/lsieve.hpp | 2 +- src/code/nt/norm_fact.hpp | 2 +- src/code/nt/pfactors.hpp | 2 +- src/code/opt/alpha_beta.hpp | 2 +- src/code/opt/astar.hpp | 4 +- src/code/{util => opt}/dlx.hpp | 10 +- src/code/opt/heuristic_lbsa.hpp | 4 +- src/code/opt/lcs_circ.hpp | 6 +- src/code/opt/lis.hpp | 4 +- src/code/opt/tsearch.hpp | 2 +- src/code/poly/comp_fps.hpp | 6 +- src/code/poly/comp_fpssps.hpp | 2 +- src/code/poly/compinv_fps.hpp | 2 +- src/code/poly/ctsh_fps.hpp | 2 +- src/code/poly/czt_fps.hpp | 2 +- src/code/poly/exp_fpssps.hpp | 2 +- src/code/poly/interp_fps.hpp | 4 +- src/code/poly/mpe_fps.hpp | 2 +- src/code/poly/poly.hpp | 27 ++- src/code/poly/pow_fps.hpp | 2 +- src/code/poly/pow_fpssp.hpp | 2 +- src/code/poly/powem_fps.hpp | 4 +- src/code/poly/shl_fps.hpp | 6 +- src/code/poly/shr_fps.hpp | 10 +- src/code/poly/sqrt_fps.hpp | 2 +- src/code/str/run_zfunc.hpp | 8 +- src/code/str/suffix_array.hpp | 6 +- src/code/tree/dfs_info.hpp | 2 +- src/code/tree/diam.hpp | 6 +- src/code/tree/lca_hld.hpp | 2 +- src/code/tree/tree_sumvw.hpp | 2 +- src/code/tree/virtual_tree.hpp | 2 +- src/code/util/odt.hpp | 1 + src/code/util/strip.hpp | 29 +++ src/code/util/traits.hpp | 48 +++-- src/code/util/util.hpp | 3 +- src/data/bzoj/1501/1.in | 10 + src/data/bzoj/1501/1.out | 10 + src/data/bzoj/1501/10.in | 10 + src/data/bzoj/1501/10.out | 10 + src/data/bzoj/1501/2.in | 10 + src/data/bzoj/1501/2.out | 10 + src/data/bzoj/1501/3.in | 10 + src/data/bzoj/1501/3.out | 10 + src/data/bzoj/1501/4.in | 10 + src/data/bzoj/1501/4.out | 1 + src/data/bzoj/1501/5.in | 10 + src/data/bzoj/1501/5.out | 10 + src/data/bzoj/1501/6.in | 10 + src/data/bzoj/1501/6.out | 10 + src/data/bzoj/1501/7.in | 10 + src/data/bzoj/1501/7.out | 10 + src/data/bzoj/1501/8.in | 10 + src/data/bzoj/1501/8.out | 10 + src/data/bzoj/1501/9.in | 10 + src/data/bzoj/1501/9.out | 1 + src/doc_md/edh/garsia_wachs.md | 4 + src/doc_md/math/josephus.md | 4 + src/doc_md/opt/dlx.md | 4 + src/doc_md/util/dlx.md | 4 - src/doc_md/util/garsia_wachs.md | 4 - src/doc_md/util/josephus.md | 4 - src/doc_md/util/strip.md | 4 + src/doc_tex/{util => edh}/garsia_wachs.tex | 0 src/doc_tex/{util => math}/josephus.tex | 0 src/doc_tex/{util => opt}/dlx.tex | 0 src/doc_tex/util/strip.tex | 0 .../pow_of_matrix.cppmeta | 3 +- .../sparse_matrix_det.cppmeta | 4 +- .../sum_of_totient_function.du-ls.cppmeta | 2 +- .../sum_of_totient_function.du-ls2.cppmeta | 2 +- .../enumerate_palindromes.cppmeta | 2 +- .../aizu-alds1/alds1_13_c.test.cpp | 17 -- .../aizu-alds1/alds1_1_b.rgcd.test.cpp | 2 +- src/test_cpverifier/aizu-dsl/dsl_2_a.test.cpp | 2 +- src/test_cpverifier/aizu-dsl/dsl_5_b.test.cpp | 2 +- src/test_cpverifier/aizu-grl/grl_3_a.test.cpp | 18 ++ src/test_cpverifier/aizu-grl/grl_3_b.test.cpp | 19 ++ .../segment_add_get_min.test.cpp | 2 +- .../staticrmq.rus4_st.test.cpp | 2 +- .../staticrmq.st_array.test.cpp | 2 +- .../biconnected_components.test.cpp | 16 +- .../chromatic_number.test.cpp | 2 +- .../two_edge_connected_components.test.cpp | 22 ++ .../intersection_of_f2_vector_spaces.test.cpp | 2 +- ..._product_mod_2.bmat-read-as-trans.test.cpp | 2 +- ...roduct_mod_2.bmat-read-then-trans.test.cpp | 2 +- .../pow_of_matrix.mintd-d31.test.cpp | 3 +- .../pow_of_matrix.mintd-d63.test.cpp | 3 +- .../pow_of_matrix.mints-s30.test.cpp | 3 +- .../pow_of_matrix.mints-s63.test.cpp | 3 +- .../sparse_matrix_det.mintd-d31.test.cpp | 4 +- .../sparse_matrix_det.mintd-d63.test.cpp | 4 +- .../sparse_matrix_det.mints-s30.test.cpp | 4 +- .../sparse_matrix_det.mints-s63.test.cpp | 4 +- ..._totient_function.du-ls.mintd-d31.test.cpp | 2 +- ..._totient_function.du-ls.mintd-d63.test.cpp | 2 +- ..._totient_function.du-ls.mints-s30.test.cpp | 2 +- ..._totient_function.du-ls.mints-s63.test.cpp | 2 +- ...totient_function.du-ls2.mintd-d31.test.cpp | 2 +- ...totient_function.du-ls2.mintd-d63.test.cpp | 2 +- ...totient_function.du-ls2.mints-s30.test.cpp | 2 +- ...totient_function.du-ls2.mints-s63.test.cpp | 2 +- .../many_aplusb.fastio.test.cpp | 1 + .../many_aplusb_128bit.fastio.test.cpp | 1 + ...cpp => many_aplusb_128bit.int128.test.cpp} | 0 ...rate_palindromes.hashstr-hashstr1.test.cpp | 2 +- ...romes.mintd-d31.hashstr-hashstr2d.test.cpp | 2 +- ...romes.mintd-d63.hashstr-hashstr2d.test.cpp | 2 +- ...romes.mints-s30.hashstr-hashstr2s.test.cpp | 2 +- ...romes.mints-s63.hashstr-hashstr2s.test.cpp | 2 +- .../unit-test/ds/st_array.bzoj1012.test.cpp | 2 +- .../garsia_wachs.bzoj3229.test.cpp | 2 +- .../{util => math}/josephus.test.cpp | 6 +- .../unit-test/nt/lsieve2.bzoj4407.test.cpp | 2 +- .../unit-test/opt/dlx.bzoj1501.test.cpp | 180 ++++++++++++++++ .../yukicoder/0502.base64.test.cpp | 2 +- .../{util => edh}/garsia_wachs.cpp | 2 +- src/test_tinplate/graph/e_bcc.cpp | 20 +- src/test_tinplate/graph/gomory_hu.cpp | 2 +- src/test_tinplate/graph/ringcnt4.cpp | 2 +- src/test_tinplate/graph/steiner_tree.cpp | 2 +- src/test_tinplate/graph/tarjan.cpp | 4 +- src/test_tinplate/graph/v_bcc.cpp | 20 +- src/test_tinplate/{util => math}/josephus.cpp | 4 +- src/test_tinplate/{util => opt}/dlx.cpp | 4 +- src/test_tinplate/str/suffix_automaton.cpp | 2 +- src/test_tinplate/tree/virtual_tree.cpp | 4 +- src/test_tinplate/util/strip.cpp | 0 208 files changed, 1032 insertions(+), 525 deletions(-) rename src/code/{util => edh}/garsia_wachs.hpp (89%) rename src/code/{util => math}/josephus.hpp (90%) rename src/code/{util => opt}/dlx.hpp (95%) create mode 100644 src/code/util/strip.hpp create mode 100644 src/data/bzoj/1501/1.in create mode 100644 src/data/bzoj/1501/1.out create mode 100644 src/data/bzoj/1501/10.in create mode 100644 src/data/bzoj/1501/10.out create mode 100644 src/data/bzoj/1501/2.in create mode 100644 src/data/bzoj/1501/2.out create mode 100644 src/data/bzoj/1501/3.in create mode 100644 src/data/bzoj/1501/3.out create mode 100644 src/data/bzoj/1501/4.in create mode 100644 src/data/bzoj/1501/4.out create mode 100644 src/data/bzoj/1501/5.in create mode 100644 src/data/bzoj/1501/5.out create mode 100644 src/data/bzoj/1501/6.in create mode 100644 src/data/bzoj/1501/6.out create mode 100644 src/data/bzoj/1501/7.in create mode 100644 src/data/bzoj/1501/7.out create mode 100644 src/data/bzoj/1501/8.in create mode 100644 src/data/bzoj/1501/8.out create mode 100644 src/data/bzoj/1501/9.in create mode 100644 src/data/bzoj/1501/9.out create mode 100644 src/doc_md/edh/garsia_wachs.md create mode 100644 src/doc_md/math/josephus.md create mode 100644 src/doc_md/opt/dlx.md delete mode 100644 src/doc_md/util/dlx.md delete mode 100644 src/doc_md/util/garsia_wachs.md delete mode 100644 src/doc_md/util/josephus.md create mode 100644 src/doc_md/util/strip.md rename src/doc_tex/{util => edh}/garsia_wachs.tex (100%) rename src/doc_tex/{util => math}/josephus.tex (100%) rename src/doc_tex/{util => opt}/dlx.tex (100%) create mode 100644 src/doc_tex/util/strip.tex delete mode 100644 src/test_cpverifier/aizu-alds1/alds1_13_c.test.cpp create mode 100644 src/test_cpverifier/aizu-grl/grl_3_a.test.cpp create mode 100644 src/test_cpverifier/aizu-grl/grl_3_b.test.cpp create mode 100644 src/test_cpverifier/library-checker-graph/two_edge_connected_components.test.cpp rename src/test_cpverifier/library-checker-sample/{many_aplusb_128bit.ios128.test.cpp => many_aplusb_128bit.int128.test.cpp} (100%) rename src/test_cpverifier/unit-test/{util => edh}/garsia_wachs.bzoj3229.test.cpp (97%) rename src/test_cpverifier/unit-test/{util => math}/josephus.test.cpp (92%) create mode 100644 src/test_cpverifier/unit-test/opt/dlx.bzoj1501.test.cpp rename src/test_tinplate/{util => edh}/garsia_wachs.cpp (95%) rename src/test_tinplate/{util => math}/josephus.cpp (95%) rename src/test_tinplate/{util => opt}/dlx.cpp (90%) create mode 100644 src/test_tinplate/util/strip.cpp diff --git a/Makefile b/Makefile index 70a4bbe9b..1c17930e5 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ SOURCES := $(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*/*.cpp)) OBJECTS := $(SOURCES:.cpp=.o) %.o: %.cpp - g++-12 -std=gnu++20 -O2 -Wall -Wextra -Wconversion -Wpedantic -Wparentheses -Wzero-as-null-pointer-constant -Wregister -Wvolatile -Wredundant-tags -Wmismatched-tags -Wextra-semi -Wstrict-null-sentinel -Wuseless-cast -Woverloaded-virtual -Wenum-conversion -Wcomma-subscript -Wno-variadic-macros -fmax-errors=1 -c $< -o $@ + g++ -std=gnu++20 -O2 -Wall -Wextra -Wconversion -Wpedantic -Wparentheses -Wzero-as-null-pointer-constant -Wregister -Wvolatile -Wredundant-tags -Wmismatched-tags -Wextra-semi -Wstrict-null-sentinel -Wuseless-cast -Woverloaded-virtual -Wenum-conversion -Wcomma-subscript -Wno-variadic-macros -fmax-errors=1 -c $< -o $@ .PHONY: all clean diff --git a/config.yml b/config.yml index bdbd16fd8..5611da149 100644 --- a/config.yml +++ b/config.yml @@ -55,10 +55,10 @@ notebook: - vec_op: vec 运算 code_ext: hpp test_ext: cpp - - ndvec: 高维 vector + - strip: strip code_ext: hpp test_ext: cpp - - dlx: DLX + - ndvec: 高维 vector code_ext: hpp test_ext: cpp - unordered_stl_hacker: unordered STL hacker @@ -70,12 +70,6 @@ notebook: - debruijn: de Bruijn 序列 code_ext: hpp test_ext: cpp - - josephus: Josephus 问题 - code_ext: hpp - test_ext: cpp - - garsia_wachs: Garsia--Wachs 算法 - code_ext: hpp - test_ext: cpp bit: - bswap: std::byteswap code_ext: hpp @@ -476,6 +470,9 @@ notebook: - alpha_beta: min-max 搜索 code_ext: hpp test_ext: cpp + - dlx: DLX + code_ext: hpp + test_ext: cpp - smawk: SMAWK 算法 code_ext: hpp test_ext: cpp @@ -982,6 +979,9 @@ notebook: - youngt: Young 表 code_ext: hpp test_ext: cpp + - josephus: Josephus 问题 + code_ext: hpp + test_ext: cpp lalg: - mat: 矩阵 code_ext: hpp @@ -1330,6 +1330,9 @@ notebook: - huffman_tree: Huffman 树 code_ext: hpp test_ext: cpp + - garsia_wachs: Garsia--Wachs 算法 + code_ext: hpp + test_ext: cpp - gray_code: Gray 码 code_ext: hpp test_ext: cpp diff --git a/src/code/conv/conv_subset.hpp b/src/code/conv/conv_subset.hpp index 4fa4f17fa..59362cef0 100644 --- a/src/code/conv/conv_subset.hpp +++ b/src/code/conv/conv_subset.hpp @@ -35,7 +35,7 @@ struct conv_subset { } CEXP vec lift(spn a) CNE { vec A(a.size()); - flt_ (u32, i, 0, (u32)a.size()) std::ranges::fill(A[i], T()), A[i][pc[i]] = a[i]; + flt_ (u32, i, 0, (u32)a.size()) fill(A[i], T()), A[i][pc[i]] = a[i]; return A; } CEXP vec unlift(spn A) CNE { diff --git a/src/code/conv/conv_u64.hpp b/src/code/conv/conv_u64.hpp index 4f0817646..6ee3e72e4 100644 --- a/src/code/conv/conv_u64.hpp +++ b/src/code/conv/conv_u64.hpp @@ -18,14 +18,14 @@ vecuu conv_u64(vec CR a, vec CR b, u32 ans_size = 0) NE { fft.bzr(n + m - 1); u32 s = fft.size(); vec pa(s), pb(s); - for (u32 i = 0; i < std::min(s, n); ++i) pa[i].real(a[i]); - for (u32 i = s; i < std::min(2 * s, n); ++i) pa[i - s].imag(a[i]); - for (u32 i = 0; i < std::min(s, m); ++i) pb[i].real(b[i]); - for (u32 i = s; i < std::min(2 * s, m); ++i) pb[i - s].imag(b[i]); + for (u32 i = 0; i < min(s, n); ++i) pa[i].real(a[i]); + for (u32 i = s; i < min(2 * s, n); ++i) pa[i - s].imag(a[i]); + for (u32 i = 0; i < min(s, m); ++i) pb[i].real(b[i]); + for (u32 i = s; i < min(2 * s, m); ++i) pb[i - s].imag(b[i]); vec pc(4 * s); auto mul = [](auto&& mul, EI* p, EI* q, EI* to, u32 n) { if (n <= 27) { - std::fill_n(to, n, 0); + fill_n(to, n, 0); flt_ (u32, i, 0, n) { flt_ (u32, j, 0, n - i) to[i + j] += p[i] * q[j]; flt_ (u32, j, n - i, n) to[i + j - n] += p[i] * q[j] * EI::w; @@ -56,7 +56,7 @@ vecuu conv_u64(vec CR a, vec CR b, u32 ans_size = 0) NE { fft.dit(to + 2 * n, m, r); flt_ (u32, i, 0, n) to[2 * n + i] *= inv; flt_ (u32, i, 0, r) fft.twiddle(to + 2 * n + m * i, m, 3 * m - 2 * m / r * i, q + m * i); - std::fill_n(to, n, 0); + fill_n(to, n, 0); flt_ (u32, i, 0, n) { to[i] += (1 - EI::w) * to[n + i] + (1 - EI::w2) * conj(q[i]); if (i + m < n) to[i + m] += (EI::w2 - EI::w) * (to[n + i] - conj(q[i])); @@ -66,8 +66,8 @@ vecuu conv_u64(vec CR a, vec CR b, u32 ans_size = 0) NE { }; mul(mul, pa.data(), pb.data(), pc.data(), s); vec ans(ans_size); - flt_ (u32, i, 0, std::min(s, ans_size)) ans[i] = pc[i].real(); - flt_ (u32, i, s, std::min(2 * s, ans_size)) ans[i] = pc[i - s].imag(); + flt_ (u32, i, 0, min(s, ans_size)) ans[i] = pc[i].real(); + flt_ (u32, i, s, min(2 * s, ans_size)) ans[i] = pc[i - s].imag(); return ans; } diff --git a/src/code/conv/fft_r2.hpp b/src/code/conv/fft_r2.hpp index cfb13c76f..ea65cacb2 100644 --- a/src/code/conv/fft_r2.hpp +++ b/src/code/conv/fft_r2.hpp @@ -19,7 +19,7 @@ class FFT_R2 { CEXP u32 size() CNE { return (u32)rev.size(); } CEXP void bzr(u32 len) NE { - const u32 n = max(std::bit_ceil(len), 2); + const u32 n = max(std::bit_ceil(len), 2_u32); if (n == size()) return; rev.resize(n, 0); const u32 k = (u32)(std::bit_width(n) - 1); diff --git a/src/code/conv/fft_r3.hpp b/src/code/conv/fft_r3.hpp index 8f2811791..50e6815ba 100644 --- a/src/code/conv/fft_r3.hpp +++ b/src/code/conv/fft_r3.hpp @@ -26,7 +26,7 @@ class FFT_R3 { CEXP void twiddle(data_t *p, u32 m, u32 t, data_t *to) CNE { assert(t <= 3 * m); if (!t || t == 3 * m) { - std::copy_n(p, m, to); + copy_n(p, m, to); return; } u32 n; diff --git a/src/code/conv/ntt_doubling.hpp b/src/code/conv/ntt_doubling.hpp index 4b448f3d4..15f6ae8bd 100644 --- a/src/code/conv/ntt_doubling.hpp +++ b/src/code/conv/ntt_doubling.hpp @@ -15,7 +15,7 @@ CEXP void ntt_doubling(NTT_t CR ntt, vec& f, u32 n = 0) NE { mint r = 1; const mint zeta = qpow(ntt.G, (mint::mod() - 1) / (n * 2)); flt_ (u32, i, 0, n) g[i] *= r, r *= zeta; - ntt.dif(g), std::ranges::copy(g, f.begin() + n); + ntt.dif(g), copy(g, f.begin() + n); } } // namespace tifa_libs::math diff --git a/src/code/ds/d_ary_heap.hpp b/src/code/ds/d_ary_heap.hpp index 82a79946d..ad98fef84 100644 --- a/src/code/ds/d_ary_heap.hpp +++ b/src/code/ds/d_ary_heap.hpp @@ -98,12 +98,16 @@ CEXP void make_dary_heap(I begin, I end, C &&comp = C{}) NE { if (begin[mdidx] = std::move(value); idx == 0) break; } } +template > +CEXP void make_dary_heap(R CR r, C &&comp = C{}) NE { return make_dary_heap(r.begin(), r.end(), std::forward(comp)); } template > CEXP bool is_dary_heap(I begin, I end, C &&comp = C{}) NE { flt_ (u32, i, 1, u32(end - begin)) if (u32 p = d_ary_heap_impl_::pidx_(i); comp(begin[p], begin[i])) return false; return true; } +template > +CEXP void is_dary_heap(R CR r, C &&comp = C{}) NE { return is_dary_heap(r.begin(), r.end(), std::forward(comp)); } template > CEXP void push_dary_heap(I begin, I end, C &&comp = C{}) NE { TPN std::iterator_traits::value_type val = std::move(end[-1]); @@ -115,6 +119,8 @@ CEXP void push_dary_heap(I begin, I end, C &&comp = C{}) NE { } begin[idx] = std::move(val); } +template > +CEXP void push_dary_heap(R CR r, C &&comp = C{}) NE { return push_dary_heap(r.begin(), r.end(), std::forward(comp)); } template > CEXP void pop_dary_heap(I begin, I end, C &&comp = C{}) NE { u32 len = u32(end - begin) - 1; @@ -133,6 +139,8 @@ CEXP void pop_dary_heap(I begin, I end, C &&comp = C{}) NE { } begin[idx] = std::move(val); } +template > +CEXP void pop_dary_heap(R CR r, C &&comp = C{}) NE { return pop_dary_heap(r.begin(), r.end(), std::forward(comp)); } } // namespace tifa_libs::ds diff --git a/src/code/ds/depq.hpp b/src/code/ds/depq.hpp index 5a96a4a4f..380e31813 100644 --- a/src/code/ds/depq.hpp +++ b/src/code/ds/depq.hpp @@ -116,6 +116,8 @@ CEXP bool is_minmax_heap(I begin, I end, C &&comp = C{}) NE { } else if (!f(i, [&](u32 c) { return c >= l || !comp(begin[i], begin[c]); })) return false; return true; } +template > +CEXP bool is_minmax_heap(R CR r, C &&comp = C{}) NE { return is_minmax_heap(r.begin(), r.end(), std::forward(comp)); } template > void push_minmax_heap(I begin, I end, C &&comp = C{}) NE { u32 len = u32(end - begin), idx = len - 1, parent = depq_impl_::pidx_(idx); @@ -147,12 +149,16 @@ void push_minmax_heap(I begin, I end, C &&comp = C{}) NE { } else break; begin[idx] = std::move(value); } +template > +CEXP bool push_minmax_heap(R CR r, C &&comp = C{}) NE { return push_minmax_heap(r.begin(), r.end(), std::forward(comp)); } template > CEXP void pop_minmax_heap_min(I begin, I end, C &&comp = C{}) NE { u32 l = u32(end - begin) - 1; if (l == 0) return; depq_impl_::pdmin_(begin, std::exchange(end[-1], std::move(begin[0])), 0, l, comp); } +template > +CEXP bool pop_minmax_heap_min(R CR r, C &&comp = C{}) NE { return pop_minmax_heap_min(r.begin(), r.end(), std::forward(comp)); } template > CEXP void pop_minmax_heap_max(I begin, I end, C &&comp = C{}) NE { u32 l = u32(end - begin) - 1; @@ -160,6 +166,8 @@ CEXP void pop_minmax_heap_max(I begin, I end, C &&comp = C{}) NE { u32 idx = 1 + !!comp(begin[1], begin[2]); depq_impl_::pdmax_(begin, std::exchange(end[-1], std::move(begin[idx])), idx, l, std::forward(comp)); } +template > +CEXP bool pop_minmax_heap_max(R CR r, C &&comp = C{}) NE { return pop_minmax_heap_max(r.begin(), r.end(), std::forward(comp)); } template > CEXP void make_minmax_heap(I begin, I end, C &&comp = C{}) NE { u32 l = u32(end - begin), idx = l / 2; @@ -207,6 +215,8 @@ CEXP void make_minmax_heap(I begin, I end, C &&comp = C{}) NE { loplim /= 2; } } +template > +CEXP bool make_minmax_heap(R CR r, C &&comp = C{}) NE { return make_minmax_heap(r.begin(), r.end(), std::forward(comp)); } } // namespace tifa_libs::ds diff --git a/src/code/ds/lichao_segtree.hpp b/src/code/ds/lichao_segtree.hpp index fe36a1136..bdd57eff0 100644 --- a/src/code/ds/lichao_segtree.hpp +++ b/src/code/ds/lichao_segtree.hpp @@ -20,7 +20,7 @@ class lichao_segtree { CEXPE lichao_segtree(spn LSH) NE : lsh(LSH.begin(), LSH.end()), t(LSH.size() * 4) { sz = (u32)lsh.size(); } // $y = ax + b~(x \in [l, r])$ - CEXP void add(T a, T b, T l, T r, u32 id = 1) NE { add(1, 0, sz - 1, u32(std::ranges::lower_bound(lsh, l) - lsh.begin()), u32(std::ranges::lower_bound(lsh, r) - lsh.begin()), {id, a, b, l, r}); } + CEXP void add(T a, T b, T l, T r, u32 id = 1) NE { add(1, 0, sz - 1, u32(lower_bound(lsh, l) - lsh.begin()), u32(lower_bound(lsh, r) - lsh.begin()), {id, a, b, l, r}); } T query(T pos) NE { return query(1, 0, sz - 1, pos); } private: diff --git a/src/code/ds/radix_heap.hpp b/src/code/ds/radix_heap.hpp index 5588062c6..bd23d7686 100644 --- a/src/code/ds/radix_heap.hpp +++ b/src/code/ds/radix_heap.hpp @@ -15,7 +15,7 @@ class radix_heap { K last; public: - CEXPE radix_heap() NE : s(0), last(0) { std::ranges::fill(ms, K(-1)); } + CEXPE radix_heap() NE : s(0), last(0) { fill(ms, K(-1)); } CEXP u32 size() CNE { return s; } CEXP bool empty() CNE { return !s; } @@ -25,7 +25,7 @@ class radix_heap { } CEXP std::pair top() NE { if (!~ms[0]) { - const u32 idx = u32(std::ranges::find_if(ms, [](auto x) NE { return !!~x; }) - ms.begin()); + const u32 idx = u32(find_if(ms, [](auto x) NE { return !!~x; }) - ms.begin()); for (last = ms[idx]; auto &p : vs[idx]) { const K b = (K)std::bit_width(p.first ^ last); vs[b].emplace_back(p), ms[b] = min(p.first, ms[b], comp); diff --git a/src/code/ds/segtree.hpp b/src/code/ds/segtree.hpp index 6744ff2b5..55a9a8bde 100644 --- a/src/code/ds/segtree.hpp +++ b/src/code/ds/segtree.hpp @@ -35,7 +35,7 @@ struct segtree { } sz = (u32)a.size(), lbn = (u32)std::bit_width(sz - 1), n = 1_u32 << lbn; if (!n) return; - val = vec(n * 2, E), std::ranges::copy(a, val.begin() + n); + val = vec(n * 2, E), copy(a, val.begin() + n); if CEXP (enable_tag) tag = vec(n, ID), vset = vecb(n); for (u32 i = n - 1; i; --i) pushup(i); } diff --git a/src/code/ds/st_array.hpp b/src/code/ds/st_array.hpp index 73efcbf39..60b5ad572 100644 --- a/src/code/ds/st_array.hpp +++ b/src/code/ds/st_array.hpp @@ -16,7 +16,7 @@ class st_array { CEXP void reset(spn a) NE { const u32 n = (u32)a.size(), lbn = (u32)std::bit_width(n); - st = vvec(lbn, vec(n)), std::ranges::copy(a, st[0].begin()); + st = vvec(lbn, vec(n)), copy(a, st[0].begin()); flt_ (u32, j, 1, lbn) flt_ (u32, i, 0, n) st[j][i] = op(st[j - 1][i], st[j - 1][(u32)max(0, i32(i - (1 << (j - 1))))]); } diff --git a/src/code/edh/base64.hpp b/src/code/edh/base64.hpp index 4cf3c4b13..9405df33e 100644 --- a/src/code/edh/base64.hpp +++ b/src/code/edh/base64.hpp @@ -13,7 +13,7 @@ class Base64 { public: static CEXP strn encode(spn a) NE { - const usz x = std::ranges::max(a), N = a.size(), B = max(6_usz, (usz)std::bit_width(x)); + const usz x = max(a), N = a.size(), B = max(6_usz, (usz)std::bit_width(x)); strn S((B * N + 11) / 6, 0); S[0] = (char)B; flt_ (usz, i, 0, N) diff --git a/src/code/edh/bwt_inv.hpp b/src/code/edh/bwt_inv.hpp index 6d2ca8dbe..b0b846e07 100644 --- a/src/code/edh/bwt_inv.hpp +++ b/src/code/edh/bwt_inv.hpp @@ -8,7 +8,7 @@ namespace tifa_libs { inline strn bwt_inv(strnv t) NE { vecu nxt(t.size()); std::iota(nxt.begin(), nxt.end(), 0); - std::ranges::stable_sort(nxt, [&t](u32 a, u32 b) NE { return t[a] < t[b]; }); + stable_sort(nxt, [&t](u32 a, u32 b) NE { return t[a] < t[b]; }); strn ret{t[nxt[0]]}; for (u32 i = nxt[0]; i;) ret += t[i = nxt[i]]; return ret; diff --git a/src/code/edh/discretization.hpp b/src/code/edh/discretization.hpp index 03a880531..bfb3133a3 100644 --- a/src/code/edh/discretization.hpp +++ b/src/code/edh/discretization.hpp @@ -2,21 +2,21 @@ #define TIFALIBS_EDH_DISCRETIZATION #include "../fast/rsort32.hpp" -#include "../util/traits.hpp" namespace tifa_libs { -template +template CEXP T uniq(T v) NE { - sort(v), v.erase(std::unique(v.begin(), v.end()), v.end()); - return v; + tifa_libs::sort(v); + auto r = unique(v.begin(), v.end()); + return {v.begin(), r.begin()}; } -template +template CEXP std::pair gen_id(T CR v) NE { const T _ = uniq(v); vecu _1; _1.reserve(v.size()); - flt_ (u32, i, 0, (u32)v.size()) _1.push_back(u32(std::ranges::lower_bound(_, v[i]) - _.begin())); + flt_ (u32, i, 0, (u32)v.size()) _1.push_back(u32(lower_bound(_, v[i]) - _.begin())); return {_, _1}; } diff --git a/src/code/util/garsia_wachs.hpp b/src/code/edh/garsia_wachs.hpp similarity index 89% rename from src/code/util/garsia_wachs.hpp rename to src/code/edh/garsia_wachs.hpp index fa16bda24..f49c31d5b 100644 --- a/src/code/util/garsia_wachs.hpp +++ b/src/code/edh/garsia_wachs.hpp @@ -1,7 +1,7 @@ -#ifndef TIFALIBS_UTIL_GARSIA_WACHS -#define TIFALIBS_UTIL_GARSIA_WACHS +#ifndef TIFALIBS_EDH_GARSIA_WACHS +#define TIFALIBS_EDH_GARSIA_WACHS -#include "util.hpp" +#include "../util/util.hpp" namespace tifa_libs { diff --git a/src/code/edh/hash_splitmix64.hpp b/src/code/edh/hash_splitmix64.hpp index 1842d8230..f5efbb999 100644 --- a/src/code/edh/hash_splitmix64.hpp +++ b/src/code/edh/hash_splitmix64.hpp @@ -1,7 +1,7 @@ #ifndef TIFALIBS_EDH_HASH_SPLITMIX64 #define TIFALIBS_EDH_HASH_SPLITMIX64 -#include "../util/traits.hpp" +#include "../util/util.hpp" namespace tifa_libs { @@ -29,7 +29,7 @@ class hash_splitmix64 { std::apply([&](Ts CR... targs) NE { ((ret = append(ret, (*this)(targs))), ...); }, tp); return ret; } - template + template u64 operator()(T CR tp) CNE { u64 ret = 0; for (auto &&i : tp) ret = append(ret, (*this)(i)); diff --git a/src/code/fast/rsort32.hpp b/src/code/fast/rsort32.hpp index 4f6cc814c..7d0613ecb 100644 --- a/src/code/fast/rsort32.hpp +++ b/src/code/fast/rsort32.hpp @@ -6,7 +6,7 @@ namespace tifa_libs { template -requires(std::contiguous_iterator && std::integral && sizeof(TPN C::value_type) == 4) +requires(std::is_array_v && std::integral()[0])> && sizeof(std::declval()[0]) == 4) || (std::contiguous_iterator && std::integral && sizeof(TPN C::value_type) == 4) void rsort32(C& a) NE { if (a.size() <= 1) return; u32 _0[256]{}, _1[256]{}, _2[256]{}, _3[256]{}; @@ -22,13 +22,14 @@ void rsort32(C& a) NE { if CEXP (std::is_signed_v) { u32 i = n; while (i && a[i - 1] < 0) --i; - std::rotate(a_, a_ + i, a_ + n); + rotate(a_, a_ + n, a_ + i); } } template +requires(std::is_array_v && std::integral()[0])> && sizeof(std::declval()[0]) == 4) || range void sort(C& a) NE { - if CEXP (std::contiguous_iterator && std::integral && sizeof(TPN C::value_type) == 4) rsort32(a); - else std::sort(a.begin(), a.end()); + if CEXP (std::is_array_v || (std::contiguous_iterator && std::integral && sizeof(TPN C::value_type) == 4)) rsort32(a); + else std::ranges::sort(a); } } // namespace tifa_libs diff --git a/src/code/game/npuzzle_data.hpp b/src/code/game/npuzzle_data.hpp index 5e3092b0f..a931fdd43 100644 --- a/src/code/game/npuzzle_data.hpp +++ b/src/code/game/npuzzle_data.hpp @@ -57,9 +57,10 @@ class NPuzzleData { swap(node[pre], node[p0]); } CEXP auto operator<=>(NPuzzleData CR r) CNE { return node <=> r.node; } + CEXP bool operator==(NPuzzleData CR r) CNE { return std::is_eq(*this <=> r); } friend auto &operator>>(istream_c auto &is, NPuzzleData &np) NE { for (auto &i : np.node) is >> i; - np.p0 = u32(std::ranges::find(np.node, 0) - np.node.begin()); + np.p0 = u32(find(np.node, 0) - np.node.begin()); flt_ (u32, p, 0, (u32)np.node.size()) if (np.node[p]) np.cost_ += costs[p][fin_pos[np.node[p]]]; return is; diff --git a/src/code/game/sudoku.hpp b/src/code/game/sudoku.hpp index f817d2fca..65cccfa85 100644 --- a/src/code/game/sudoku.hpp +++ b/src/code/game/sudoku.hpp @@ -2,7 +2,7 @@ #define TIFALIBS_GAME_SUDOKU #include "../math/isqrt.hpp" -#include "../util/dlx.hpp" +#include "../opt/dlx.hpp" namespace tifa_libs::game { @@ -21,7 +21,7 @@ CEXP v3ecu sudoku_solver(cT_(vvecu) data, bool get_all_solution = false) NE { } if (!not_filled) return {data}; v3ecu ans; - util::DLX(g, get_all_solution).dance([&](spnu res) NE -> void { + opt::DLX(g, get_all_solution).dance([&](spnu res) NE -> void { vvecu dt = data; for (u32 _ : res) dt[(_ - 1) % n4 / n2][(_ - 1) % n2] = (_ - 1) / n4 + 1; ans.push_back(dt); diff --git a/src/code/geo2d/any_ins_ss.hpp b/src/code/geo2d/any_ins_ss.hpp index e95ae6499..2a2c71b98 100644 --- a/src/code/geo2d/any_ins_ss.hpp +++ b/src/code/geo2d/any_ins_ss.hpp @@ -24,7 +24,7 @@ CEXP bool any_ins_Ss(vec> CR ss) NE { if (is_gt(seg.l.x, seg.r.x)) swap(seg.l, seg.r); seq.emplace_back(seg.l.x, 0, seg), seq.emplace_back(seg.r.x, 1, seg); } - std::ranges::sort(seq, seqcmp); + sort(seq, seqcmp); FP x_now; auto cmp = [&](line CR u, line CR v) NE { if (is_eq(u.l.x, u.r.x) || is_eq(v.l.x, v.r.x)) return is_lt(u.l.y, v.l.y); diff --git a/src/code/geo2d/argsort.hpp b/src/code/geo2d/argsort.hpp index fe01a99a2..b902b38f3 100644 --- a/src/code/geo2d/argsort.hpp +++ b/src/code/geo2d/argsort.hpp @@ -9,7 +9,7 @@ namespace tifa_libs::geo { template CEXP void argsort(vec> &vp, u32 quad_start = 6) NE { assert(quad_start < 9); - std::ranges::sort(vp, [ofs = 9 - quad_start](point CR l, point CR r) NE { return l.quad() == r.quad() ? is_pos(l ^ r) : (l.quad() + ofs) % 9 < (r.quad() + ofs) % 9; }); + sort(vp, [ofs = 9 - quad_start](point CR l, point CR r) NE { return l.quad() == r.quad() ? is_pos(l ^ r) : (l.quad() + ofs) % 9 < (r.quad() + ofs) % 9; }); } } // namespace tifa_libs::geo diff --git a/src/code/geo2d/aunion_cs.hpp b/src/code/geo2d/aunion_cs.hpp index 95acb3953..f6f0e2206 100644 --- a/src/code/geo2d/aunion_cs.hpp +++ b/src/code/geo2d/aunion_cs.hpp @@ -18,6 +18,7 @@ CEXP vec aunion_Cs(vec> CR cs) NE { if (auto CR c = comp(_1, r._1); c) return c; return comp(_2, r._2); } + CEXP bool operator==(arc_t CR r) CNE { return (*this <=> r) == 0; } }; const u32 n = (u32)cs.size(); vvec arcs(n); @@ -45,7 +46,7 @@ CEXP vec aunion_Cs(vec> CR cs) NE { } else evt.emplace_back(argl, 1), evt.emplace_back(argr, -1); } } - std::ranges::sort(evt); + sort(evt); int sum = init; flt_ (u32, i, 0, (u32)evt.size()) { sum += evt[i].second; @@ -66,7 +67,7 @@ CEXP vec aunion_Cs(vec> CR cs) NE { vec ans(n); flt_ (u32, i, 0, n) { FP sum = 0; - std::sort(arcs[i].begin(), arcs[i].end()); + sort(arcs[i]); u32 cnt = 0; flt_ (u32, j, 0, (u32)arcs[i].size()) if (j > 0 && eq(arcs[i][j], arcs[i][j - 1])) arcs[i + (++cnt)].push_back(arcs[i][j]); diff --git a/src/code/geo2d/aunion_pos.hpp b/src/code/geo2d/aunion_pos.hpp index 1f98594b5..31ef76b07 100644 --- a/src/code/geo2d/aunion_pos.hpp +++ b/src/code/geo2d/aunion_pos.hpp @@ -29,7 +29,7 @@ CEXP vec aunion_Pos(vec> CR pos) NE { } } } - if (std::ranges::sort(evt); e.l > e.r) std::ranges::reverse(evt); + if (sort(evt); e.l > e.r) reverse(evt); int sum = 0; flt_ (u32, i, 0, (u32)evt.size()) { sum += evt[i].second; @@ -44,7 +44,7 @@ CEXP vec aunion_Pos(vec> CR pos) NE { } vec ans(n); flt_ (u32, i, 0, n) { - std::ranges::sort(segs[i]); + sort(segs[i]); FP sum = 0; u32 cnt = 0; flt_ (u32, j, 0, (u32)segs[i].size()) { diff --git a/src/code/geo2d/circle.hpp b/src/code/geo2d/circle.hpp index 3dbcaec52..b634a8ec1 100644 --- a/src/code/geo2d/circle.hpp +++ b/src/code/geo2d/circle.hpp @@ -17,7 +17,10 @@ struct circle { friend auto &operator>>(istream_c auto &is, circle &c) NE { return is >> c.o >> c.r; } friend auto &operator<<(ostream_c auto &os, circle CR c) NE { return os << c.o << ' ' << c.r; } friend CEXP bool operator==(circle CR l, circle CR r) NE { return l.o == r.o && l.r == r.r; } - friend CEXP bool operator<(circle CR l, circle CR r) NE { return l.o == r.o ? l.r < r.r : l.o < r.o; } + friend CEXP auto operator<=>(circle CR l, circle CR r) NE { + if (auto c = l.o <=> r.o; c) return c; + return comp(l.r, r.r); + } CEXP FP area(FP angle = pi_v * 2) CNE { return angle * r * r / 2; } CEXP FP crown_area(FP angle = pi_v * 2) CNE { return (angle - std::sin(angle)) * r * r / 2; } diff --git a/src/code/geo2d/cvh.hpp b/src/code/geo2d/cvh.hpp index ee31d41ca..a61082f54 100644 --- a/src/code/geo2d/cvh.hpp +++ b/src/code/geo2d/cvh.hpp @@ -46,12 +46,12 @@ struct cvh : public polygon { u32 p = 0; flt_ (u32, i, 1, m - 1) if (cvh[i] < cvh[p]) p = i; - std::ranges::rotate(cvh, cvh.begin() + p), this->vs = cvh; + rotate(cvh, cvh.begin() + p), this->vs = cvh; return *this; } // @return true if @p in convex hull (include border) CEXP bool contains(point CR p) CNE { - auto it = std::lower_bound(this->vs.begin() + 1, this->vs.end(), p, [&](point CR l, point CR r) NE { return is_pos(cross((*this)[0], l, r)); }) - 1; + auto it = lower_bound(this->vs.begin() + 1, this->vs.end(), p, [&](point CR l, point CR r) NE { return is_pos(cross((*this)[0], l, r)); }) - 1; auto next_it = this->next(it); if (auto res = sgn_cross(p, *it, *next_it); res) return ~res; else return !res && !is_pos(dot(p, *it, *next_it)); diff --git a/src/code/geo2d/dcvh.hpp b/src/code/geo2d/dcvh.hpp index 911e4b814..657e919ea 100644 --- a/src/code/geo2d/dcvh.hpp +++ b/src/code/geo2d/dcvh.hpp @@ -59,8 +59,8 @@ class dcvh { } CEXP cvh to_CVH() CNE { cvh ret; - std::ranges::copy(hcvh_up.vs, ret.vs.begin()); - std::ranges::copy(hcvh_down.vs, std::back_inserter(ret.vs)); + copy(hcvh_up.vs, ret.vs.begin()); + copy(hcvh_down.vs, std::back_inserter(ret.vs)); argsort(ret.vs); return ret; } diff --git a/src/code/geo2d/femwebp.hpp b/src/code/geo2d/femwebp.hpp index 5a740f862..cd92d01ca 100644 --- a/src/code/geo2d/femwebp.hpp +++ b/src/code/geo2d/femwebp.hpp @@ -24,7 +24,7 @@ point femwebp(vec> CR vp) NE { return r.norm(); }; auto T = [&](point CR y) NE { - if (!std::ranges::count(vp, y)) return Tl(y); + if (!count(vp, y)) return Tl(y); FP er = 1 / r(y); return max((FP)0, 1 - er) * Tl(y) + min((FP)1, er) * y; }; diff --git a/src/code/geo2d/max_cover_ps.hpp b/src/code/geo2d/max_cover_ps.hpp index 6b31b5933..f01ea12aa 100644 --- a/src/code/geo2d/max_cover_ps.hpp +++ b/src/code/geo2d/max_cover_ps.hpp @@ -22,7 +22,7 @@ CEXP u64 max_cover_Ps(vec> CR vp, FP r) NE { FP delta = std::acos(dist / diam), polar = ang2pi_PP(vp[i], vp[j]); angs.emplace_back(polar - delta, 1), angs.emplace_back(polar + delta, -1); } - std::ranges::sort(angs); + sort(angs); u64 sum = 0; flt_ (u32, j, 0, (u32)angs.size()) ans = max(ans, sum += angs[j].second); } diff --git a/src/code/geo2d/maxv_cvh_cnt.hpp b/src/code/geo2d/maxv_cvh_cnt.hpp index 2e5c5e97a..7b341e25a 100644 --- a/src/code/geo2d/maxv_cvh_cnt.hpp +++ b/src/code/geo2d/maxv_cvh_cnt.hpp @@ -15,16 +15,17 @@ CEXP u32 maxv_cvh_cnt(vec> CR vp) NE { u32 l, r; CEXP TIFA(u32 l, u32 r, point CR pl, point CR pr) NE : ln(pl, pr), l(l), r(r) {} CEXP auto operator<=>(TIFA CR r) CNE { return ln <=> r.ln; } + CEXP bool operator==(TIFA CR r) CNE = default; }; vec vl; flt_ (u32, i, 0, n) flt_ (u32, j, 0, n) if (i != j) vl.emplace_back(i, j, vp[i], vp[j]); - std::sort(vl.begin(), vl.end()); + sort(vl); veci f(n + 1); u32 ans = 0; flt_ (u32, i, 0, n) { - std::ranges::fill(f, INT32_MIN), f[i] = 0; + fill(f, INT32_MIN), f[i] = 0; flt_ (u32, j, 0, (u32)vl.size()) f[vl[j].r] = max(f[vl[j].r], f[vl[j].l] + 1); ans = (u32)max((i32)ans, f[i]); } diff --git a/src/code/geo2d/min_dis_ps.hpp b/src/code/geo2d/min_dis_ps.hpp index 1b042909d..b4a1b3a12 100644 --- a/src/code/geo2d/min_dis_ps.hpp +++ b/src/code/geo2d/min_dis_ps.hpp @@ -18,7 +18,7 @@ CEXP pttu min_dis_Ps(vec> CR vp) NE { vec vpi; vpi.reserve(n); flt_ (u32, i, 0, n) vpi.emplace_back(vp[i], i); - std::ranges::sort(vpi); + sort(vpi); FP d = std::numeric_limits::max(); u32 a = -1_u32, b = -1_u32; auto upd = [&](T CR x, T CR y) NE { diff --git a/src/code/geo2d/point.hpp b/src/code/geo2d/point.hpp index 01b3d6b80..151f4653a 100644 --- a/src/code/geo2d/point.hpp +++ b/src/code/geo2d/point.hpp @@ -57,7 +57,7 @@ struct point { if (auto CR c = comp(x, p.x); c) return c; return comp(y, p.y); } - CEXP bool operator==(point CR p) CNE { return is_eq(x, p.x) && is_eq(y, p.y); } + CEXP bool operator==(point CR p) CNE { return (*this <=> p) == 0; } CEXP FP operator*(point CR p) CNE { return x * p.x + y * p.y; } CEXP FP operator^(point CR p) CNE { return x * p.y - y * p.x; } CEXP FP arg() CNE { diff --git a/src/code/geo2d/polygon.hpp b/src/code/geo2d/polygon.hpp index ed539d089..1268e97ab 100644 --- a/src/code/geo2d/polygon.hpp +++ b/src/code/geo2d/polygon.hpp @@ -30,7 +30,7 @@ struct polygon { CEXP point &operator[](u32 x) NE { return vs[x]; } CEXP point CR operator[](u32 x) CNE { return vs[x]; } CEXP polygon &resort() NE { - std::ranges::sort(vs); + sort(vs); return *this; } CEXP polygon &reunique() NE { diff --git a/src/code/geo3d/cvh3d.hpp b/src/code/geo3d/cvh3d.hpp index e846c64f8..a2cda8bd6 100644 --- a/src/code/geo3d/cvh3d.hpp +++ b/src/code/geo3d/cvh3d.hpp @@ -129,10 +129,7 @@ class cvh3d { if (*faces[fstf].p.v == *faces[lastf].p.u) faces[fstf].n[1] = lastf, faces[lastf].n[2] = fstf; else faces[fstf].n[2] = lastf, faces[lastf].n[1] = fstf; resptid.clear(); - for (auto i : resfdel) { - std::ranges::move(ptsid[i], std::back_inserter(resptid)); - ptsid[i].clear(); - } + for (auto i : resfdel) move(ptsid[i], std::back_inserter(resptid)), ptsid[i].clear(); for (auto i : resptid) { if (vp[i] == p) continue; for (auto j : resfnew) diff --git a/src/code/geo3d/point3d.hpp b/src/code/geo3d/point3d.hpp index 77a9b3756..e5cefcbbc 100644 --- a/src/code/geo3d/point3d.hpp +++ b/src/code/geo3d/point3d.hpp @@ -53,7 +53,7 @@ struct point3d { if (auto c = comp(y, p.y); c) return c; return comp(z, p.z); } - CEXP bool operator==(point3d CR p) CNE { return is_eq(x, p.x) && is_eq(y, p.y) && is_eq(z, p.z); } + CEXP bool operator==(point3d CR p) CNE { return (*this <=> p) == 0; } CEXP FP operator*(point3d CR p) CNE { return x * p.x + y * p.y + z * p.z; } CEXP point3d operator^(point3d CR p) CNE { return point3d{y * p.z - z * p.y, z * p.x - x * p.z, x * p.y - y * p.x}; } CEXP auto norm2() CNE { return x * x + y * y + z * z; } diff --git a/src/code/graph/alist.hpp b/src/code/graph/alist.hpp index 8d4d6b373..6d6b4ef21 100644 --- a/src/code/graph/alist.hpp +++ b/src/code/graph/alist.hpp @@ -19,10 +19,16 @@ struct alist { g[u].push_back(v); if CEXP (++cnt_arc; with_deg) ++deg_in[v], ++deg_out[u]; } + CEXP void add_edge(u32 u, u32 v) NE { add_arc(u, v), add_arc(v, u); } CEXP void build() CNE {} CEXP u32 size() CNE { return (u32)g.size(); } CEXP auto& operator[](u32 u) NE { return g[u]; } CEXP auto CR operator[](u32 u) CNE { return g[u]; } + template + requires requires(F f, u32 v) { f(v); } + CEXP void foreach(u32 u, F&& f) CNE { + for (auto v : g[u]) f(v); + } }; template struct alistw { @@ -38,10 +44,16 @@ struct alistw { g[u].emplace_back(v, w); if CEXP (++cnt_arc; with_deg) ++deg_in[v], ++deg_out[u]; } + CEXP void add_edge(u32 u, u32 v, cT_(T) w) NE { add_arc(u, v, w), add_arc(v, u, w); } CEXP void build() CNE {} CEXP u32 size() CNE { return (u32)g.size(); } CEXP auto& operator[](u32 u) NE { return g[u]; } CEXP auto CR operator[](u32 u) CNE { return g[u]; } + template + requires requires(F f, u32 v, T w) { f(v, w); } + CEXP void foreach(u32 u, F&& f) CNE { + for (auto [v, w] : g[u]) f(v, w); + } }; } // namespace tifa_libs::graph diff --git a/src/code/graph/alists.hpp b/src/code/graph/alists.hpp index c71ac8e85..b2641ec8f 100644 --- a/src/code/graph/alists.hpp +++ b/src/code/graph/alists.hpp @@ -50,6 +50,7 @@ class alists { //! DO NOT call this after called %build template CEXP void add_arc(u32 u, Ts&&... args) NE { b.emplace_back(u, ET{std::forward(args)...}), ++h[u]; } + CEXP void add_edge(u32 u, u32 v) NE { add_arc(u, v), add_arc(v, u); } CEXP void build() NE { if (cnt_arc) return; std::inclusive_scan(h.begin(), h.end(), h.begin()); @@ -60,6 +61,13 @@ class alists { CEXP u32 size() CNE { return h.size() - 1; } CEXP Es::iterator> operator[](u32 u) NE { return {e.begin() + h[u], e.begin() + h[u + 1]}; } CEXP const Es::const_iterator> operator[](u32 u) CNE { return {e.begin() + h[u], e.begin() + h[u + 1]}; } + template + CEXP void foreach(u32 u, F&& f) CNE { + if CEXP (std::is_void_v) + for (auto to : (*this)[u]) f(to); + else + for (auto [to, cost] : (*this)[u]) f(to, cost); + } }; } // namespace tifa_libs::graph diff --git a/src/code/graph/blossomw.hpp b/src/code/graph/blossomw.hpp index c0a234cc9..65f6e54e1 100644 --- a/src/code/graph/blossomw.hpp +++ b/src/code/graph/blossomw.hpp @@ -66,8 +66,8 @@ struct blossomw { for (auto t : flo[x]) set_st(t, b); } CEXP u32 get_pr(u32 b, u32 xr) NE { - if (u32 pr = u32(std::ranges::find(flo[b], xr) - flo[b].begin()); pr & 1) { - std::reverse(flo[b].begin() + 1, flo[b].end()); + if (u32 pr = u32(find(flo[b], xr) - flo[b].begin()); pr & 1) { + reverse(flo[b].begin() + 1, flo[b].end()); return u32(flo[b].size() - pr); } else return pr; } @@ -76,7 +76,7 @@ struct blossomw { if (match[u] = ev; u <= n) return; u32 xr = flo_from[u][eu], pr = get_pr(u, xr); flt_ (u32, i, 0, pr) set_match(flo[u][i], flo[u][i ^ 1]); - set_match(xr, v), std::rotate(flo[u].begin(), flo[u].begin() + pr, flo[u].end()); + set_match(xr, v), rotate(flo[u], flo[u].begin() + pr); } CEXP void augment(u32 u, u32 v) NE { while (1) { @@ -102,7 +102,7 @@ struct blossomw { auto blossom = [&](u32 x) NE { for (u32 y; x != anc; x = st[par[y]]) flo[b].push_back(x), flo[b].push_back(y = st[match[x]]), q_push(y); }; - blossom(u), std::reverse(flo[b].begin() + 1, flo[b].end()), blossom(v), set_st(b, b); + blossom(u), reverse(flo[b].begin() + 1, flo[b].end()), blossom(v), set_st(b, b); flt_ (u32, x, 1, nx + 1) g[b][x].w = g[x][b].w = 0; flt_ (u32, x, 1, n + 1) flo_from[b][x] = 0; for (auto xs : flo[b]) { diff --git a/src/code/graph/bm.hpp b/src/code/graph/bm.hpp index 4d70ddce4..6faea0bec 100644 --- a/src/code/graph/bm.hpp +++ b/src/code/graph/bm.hpp @@ -8,7 +8,7 @@ namespace tifa_libs::graph { // cb_relax(now, to) // @return false if negative cycle detected -template +template requires(!uint_c) && requires(F relex, u32 now, u32 to) { relex(now, to); } bool bellman_ford(G CR g, u32 s, F &&cb_relax, vec &dis) NE { const u32 n = g.size(), sn = math::isqrt(n); @@ -34,10 +34,11 @@ bool bellman_ford(G CR g, u32 s, F &&cb_relax, vec &dis) NE { return true; } // cb_relax(now, to) -template +template std::optional> bellman_ford(G CR g, u32 s, F &&cb_relax, TPN G::w_t INF = std::numeric_limits::max() / 2 - 1) NE { vec dis(g.size(), INF); - return bellman_ford(g, s, std::forward(cb_relax), dis) ? std::optional{dis} : std::nullopt; + if (bellman_ford(g, s, std::forward(cb_relax), dis)) return dis; + return {}; } } // namespace tifa_libs::graph diff --git a/src/code/graph/chordal.hpp b/src/code/graph/chordal.hpp index 412b87ef8..958d60596 100644 --- a/src/code/graph/chordal.hpp +++ b/src/code/graph/chordal.hpp @@ -6,7 +6,7 @@ namespace tifa_libs::graph { template -requires(adjlist_c && !adjlistw_c) +requires(alist_c && !alistw_c) class chordal { G CR g; vecu deg; @@ -32,7 +32,7 @@ class chordal { if (~idx[to]) ++deg[to], del(to), ins(to, n + (++idx[to])); peo[i] = v; } - std::ranges::reverse(peo); + reverse(peo); flt_ (u32, i, 0, n) rnk[peo[i]] = i; } @@ -44,7 +44,7 @@ class chordal { if (rnk[u] < rnk[v]) if (s.push_back(v); rnk[s.back()] < rnk[s[0]]) swap(s[0], s.back()); flt_ (u32, j, 1, (u32)s.size()) - if (!std::ranges::binary_search(g[s[0]], s[j])) { + if (!binary_search(g[s[0]], s[j])) { if CEXP (!find_indcycle) return false; else { u32 x = s[j], y = s[0], z = u; @@ -52,7 +52,7 @@ class chordal { std::queue q({x}); while (!q.empty()) { u32 t = q.front(); - if (q.pop(); std::ranges::binary_search(g[t], y)) { + if (q.pop(); binary_search(g[t], y)) { pre[y] = t; vecu path = {y}; while (path.back() != x) path.push_back(pre[path.back()]); @@ -60,7 +60,7 @@ class chordal { return path; } for (u32 u : g[t]) - if (u != z && !std::ranges::binary_search(g[u], z) && !~pre[u]) pre[u] = t, q.push(u); + if (u != z && !binary_search(g[u], z) && !~pre[u]) pre[u] = t, q.push(u); } } } @@ -81,7 +81,7 @@ class chordal { } return res; } - CEXP u32 chromatic_number() CNE { return std::ranges::max(deg) + 1; } + CEXP u32 chromatic_number() CNE { return max(deg) + 1; } CEXP vecu max_independent_set() CNE { vecu res; for (vecb vis(peo.size()); u32 u : peo) { diff --git a/src/code/graph/chrom_num.hpp b/src/code/graph/chrom_num.hpp index 5c8967299..59d921f11 100644 --- a/src/code/graph/chrom_num.hpp +++ b/src/code/graph/chrom_num.hpp @@ -18,7 +18,7 @@ CEXP u32 calc(u32 n, vecpti hist) NE { } } // namespace chrom_num_impl_ -CEXP u32 chrom_num(adjlist_c auto CR g) NE { +CEXP u32 chrom_num(alist_c auto CR g) NE { const u32 n = g.size(); vecu adj(n), dp(1 << n); flt_ (u32, i, 0, n) diff --git a/src/code/graph/dijkstra.hpp b/src/code/graph/dijkstra.hpp index c91808522..18d729ddc 100644 --- a/src/code/graph/dijkstra.hpp +++ b/src/code/graph/dijkstra.hpp @@ -7,7 +7,7 @@ namespace tifa_libs::graph { // relax(now, to) -template +template requires(!sint_c) && requires(F relex, u32 now, u32 to) { relex(now, to); } CEXP vec dijkstra(G CR g, u32 s, F &&relax, T INF = std::numeric_limits::max() / 2 - 1) NE { vec dis(g.size(), INF); diff --git a/src/code/graph/domtree.hpp b/src/code/graph/domtree.hpp index 522fc07ed..3e19dbc76 100644 --- a/src/code/graph/domtree.hpp +++ b/src/code/graph/domtree.hpp @@ -6,7 +6,7 @@ namespace tifa_libs::graph { template -requires(adjlist_c && !adjlistw_c) +requires(alist_c && !alistw_c) class domtree { u32 n, t; G CR g; diff --git a/src/code/graph/e_bcc.hpp b/src/code/graph/e_bcc.hpp index a97c868e5..6a7ec11ac 100644 --- a/src/code/graph/e_bcc.hpp +++ b/src/code/graph/e_bcc.hpp @@ -1,45 +1,36 @@ #ifndef TIFALIBS_GRAPH_E_BCC #define TIFALIBS_GRAPH_E_BCC -#include "../util/util.hpp" +#include "eog.hpp" namespace tifa_libs::graph { -template -class e_bcc { - vvec CR g; - - public: - u32 id; - vecu ebcc_id, dfn, low; - vecb cut; +struct e_bcc { + vecu dfn, low; vvecu belongs; - //! EW need rev_edge - CEXPE e_bcc(vvec CR G) NE : g(G) { build(); } - - CEXP void build() NE { - u32 cnt = 0, n = u32(g.size()); - id = 0, dfn = low = ebcc_id = vecu(n, n), cut = vecb(n, 0); - vecu s; - auto f = [&](auto &&f, u32 u, u32 fa, u32 inv_from) NE -> void { - dfn[u] = low[u] = cnt++, s.push_back(u); - flt_ (u32, i, 0, (u32)g[u].size()) { - auto v = g[u][i]; - if (v.to == fa && i == inv_from) continue; - if (dfn[v.to] == n) f(f, v.to, u, v.inv), low[u] = min(low[u], low[v.to]); - else low[u] = min(low[u], dfn[v.to]); - } + //! g should be undirect + template + CEXP e_bcc(eog CR g) NE : dfn(g.size()), low(g.size()) { + vecu stk; + u32 tot = 0; + auto tarjan = [&](auto&& f, u32 u, u32 fa_eid) -> void { + dfn[u] = low[u] = ++tot; + stk.push_back(u); + g.foreach(u, [&](u32 eid, u32 v, u32) { + if (!dfn[v]) f(f, v, eid), low[u] = min(low[u], low[v]); + else if (eid != fa_eid && eid != (fa_eid ^ 1)) low[u] = min(low[u], dfn[v]); + }); if (low[u] == dfn[u]) { - belongs.push_back(vecu()); - do { - const u32 v = s.back(); - if (s.pop_back(), ebcc_id[v] = id, belongs[id].push_back(v); v == u) return void(++id); - } while (1); + vecu res; + u32 p; + do res.push_back(p = stk.back()), stk.pop_back(); + while (u != p); + belongs.emplace_back(std::move(res)); } }; - flt_ (u32, i, 0, n) - if (dfn[i] == n) f(f, i, i, -1_u32); + flt_ (u32, i, 0, g.size()) + if (!dfn[i]) tarjan(tarjan, i, -1_u32); } }; diff --git a/src/code/graph/eog.hpp b/src/code/graph/eog.hpp index a2ac1222b..30073fa73 100644 --- a/src/code/graph/eog.hpp +++ b/src/code/graph/eog.hpp @@ -7,6 +7,7 @@ namespace tifa_libs::graph { template struct eog { + using w_t = void; vecu head; vecptu e; u32 cnt_arc; @@ -15,21 +16,30 @@ struct eog { CEXPE eog(u32 n = 0) NE : head(n, -1_u32), e(), cnt_arc{0}, deg_in(0), deg_out(0) { if CEXP (with_deg) deg_in.resize(n), deg_out.resize(n); } + CEXP u32 size() CNE { return (u32)head.size(); } CEXP void add_arc(u32 u, u32 v) NE { e.emplace_back(v, head[u]), head[u] = u32(e.size() - 1); if CEXP (++cnt_arc; with_deg) ++deg_in[v], ++deg_out[u]; } + CEXP void add_edge(u32 u, u32 v) NE { add_arc(u, v), add_arc(v, u); } CEXP void pop_startwith(u32 now) NE { if CEXP (--cnt_arc; with_deg) --deg_in[e[head[now]].first], --deg_out[now]; head[now] = e[head[now]].second; } + CEXP auto& operator[](u32 u) NE { return e[u]; } + CEXP auto CR operator[](u32 u) CNE { return e[u]; } + template + requires requires(F f, u32 eid, u32 to, u32 next) { f(eid, to, next); } + CEXP void foreach(u32 u, F&& f) CNE { + for (u32 i = head[u]; ~i; i = e[i].second) f(i, e[i].first, e[i].second); + } }; template struct eogw { + using w_t = T; // clang-format off struct TIFA { u32 to; T w; u32 nxt; }; // clang-format on - using w_t = T; vecu head; vec e; u32 cnt_arc; @@ -38,14 +48,23 @@ struct eogw { CEXPE eogw(u32 n = 0) NE : head(n, -1_u32), e(), cnt_arc{0}, deg_in(0), deg_out(0) { if CEXP (with_deg) deg_in.resize(n), deg_out.resize(n); } + CEXP u32 size() CNE { return (u32)head.size(); } CEXP void add_arc(u32 u, u32 v, cT_(T) w) NE { e.emplace_back(v, w, head[u]), head[u] = u32(e.size() - 1); if CEXP (++cnt_arc; with_deg) ++deg_in[v], ++deg_out[u]; } + CEXP void add_edge(u32 u, u32 v, cT_(T) w) NE { add_arc(u, v, w), add_arc(v, u, w); } CEXP void pop_startwith(u32 now) NE { if CEXP (--cnt_arc; with_deg) --deg_in[e[head[now]].first], --deg_out[now]; head[now] = e[head[now]].second; } + CEXP auto& operator[](u32 u) NE { return e[u]; } + CEXP auto CR operator[](u32 u) CNE { return e[u]; } + template + requires requires(F f, u32 eid, u32 to, T w, u32 next) { f(eid, to, next, w); } + CEXP void foreach(u32 u, F&& f) CNE { + for (u32 i = head[u]; ~i; i = e[i].second) f(i, e[i].to, e[i].w, e[i].nxt); + } }; } // namespace tifa_libs::graph diff --git a/src/code/graph/euler_trail.hpp b/src/code/graph/euler_trail.hpp index e0ad1bc5d..caf0bf111 100644 --- a/src/code/graph/euler_trail.hpp +++ b/src/code/graph/euler_trail.hpp @@ -25,7 +25,7 @@ CEXP std::optional run_(u32 n, u32 m, cT_(vvecptu) g, u32 s) NE { if (ret.size() != m + 1) return {}; for (i32 i : f) if (i < 0) return {}; - std::ranges::reverse(ret); + reverse(ret); return ret; } } // namespace euler_trail_impl_ @@ -53,7 +53,7 @@ CEXP std::optional euler_trail(u32 n, vecptu CR edges) NE { } else if (g[i].size() & 1) s = i; return euler_trail_impl_::run_(n, (u32)edges.size(), g, s); } -CEXP bool is_eulerian(adjlist_c auto CR g) NE { +CEXP bool is_eulerian(alist_c auto CR g) NE { const u32 n = g.size(); assert(n == g.deg_in.size()); vecb vis(n); diff --git a/src/code/graph/find_cycle.hpp b/src/code/graph/find_cycle.hpp index 1ebd7a79c..61959716d 100644 --- a/src/code/graph/find_cycle.hpp +++ b/src/code/graph/find_cycle.hpp @@ -6,7 +6,7 @@ namespace tifa_libs::graph { template -requires(adjlist_c && !adjlistw_c) +requires(alist_c && !alistw_c) CEXP vecptu find_cycle(G CR g) NE { flt_ (u32, i, 0, g.size()) for (auto j : g[i]) @@ -37,7 +37,7 @@ CEXP vecptu find_cycle(G CR g) NE { flt_ (u32, i, 0, g.size()) { if (vis[i]) continue; if (f(f, i, i, -1_u32); fin) { - std::ranges::reverse(cycle); + reverse(cycle); return cycle; } } diff --git a/src/code/graph/johnson.hpp b/src/code/graph/johnson.hpp index c8156b9c7..9c898eb4e 100644 --- a/src/code/graph/johnson.hpp +++ b/src/code/graph/johnson.hpp @@ -14,9 +14,9 @@ CEXP std::optional> johnson(u32 n, vec> CR arcs, T const INF = vvec dis(n); alistw g(n); for (auto [w, u, v] : arcs) g.add_arc(u, v, w); - if CEXP (!is_sint_v) { + if CEXP (!sint_c) flt_ (u32, i, 0, n) dis[i] = dijkstra(g, i, fn_0, INF); - } else { + else { g.g.push_back({}); flt_ (u32, i, 0, n) g.add_arc(n, i, 0); auto h = bellman_ford(g, n, fn_0, INF); diff --git a/src/code/graph/kosaraju.hpp b/src/code/graph/kosaraju.hpp index bf159d17d..75d7e5076 100644 --- a/src/code/graph/kosaraju.hpp +++ b/src/code/graph/kosaraju.hpp @@ -32,7 +32,7 @@ class kosaraju { for (scc_id[idx] = cnt; auto to : rev_g[idx]) rdfs(rdfs, to, cnt); }; flt_ (u32, i, 0, (u32)g.size()) dfs(dfs, i); - std::ranges::reverse(ord), scc_id.resize(g.size(), -1_u32); + reverse(ord), scc_id.resize(g.size(), -1_u32); u32 cnt = 0; for (u32 i : ord) if (!~scc_id[i]) rdfs(rdfs, i, cnt++); diff --git a/src/code/graph/make_alistr.hpp b/src/code/graph/make_alistr.hpp index 1758e07f5..0070049d7 100644 --- a/src/code/graph/make_alistr.hpp +++ b/src/code/graph/make_alistr.hpp @@ -5,12 +5,12 @@ namespace tifa_libs::graph { -template +template CEXP auto make_alistr(G CR g) NE { const u32 n = g.size(); G ret(n); flt_ (u32, u, 0, n) - if CEXP (adjlistw_c) + if CEXP (alistw_c) for (auto&& [v, w] : g[u]) ret.add_arc(v, u, w); else for (auto v : g[u]) ret.add_arc(v, u); diff --git a/src/code/graph/manhattan_mst.hpp b/src/code/graph/manhattan_mst.hpp index b9635a01d..289ce5c8e 100644 --- a/src/code/graph/manhattan_mst.hpp +++ b/src/code/graph/manhattan_mst.hpp @@ -14,7 +14,7 @@ vec> manhattan_mst(vecpt vp) NE { std::iota(id.begin(), id.end(), 0); vec> ret; flt_ (u32, k, 0, 4) { - std::ranges::sort(id, [&](u32 i, u32 j) NE { return vp[i].first + vp[i].second < vp[j].first + vp[j].second; }); + sort(id, {}, [&](u32 i) NE { return vp[i].first + vp[i].second; }); for (map mp; auto i : id) { for (auto it = mp.lower_bound(-vp[i].second); it != mp.end(); mp.erase(it++)) { u32 j = it->second; diff --git a/src/code/graph/min_cycle_mean.hpp b/src/code/graph/min_cycle_mean.hpp index 9e9e206a0..da21b5bec 100644 --- a/src/code/graph/min_cycle_mean.hpp +++ b/src/code/graph/min_cycle_mean.hpp @@ -9,17 +9,17 @@ template CEXP T min_cycle_mean(vec> CR edges, u32 n, T INF = std::numeric_limits::max() / 2 - 1) NE { vec d(n + 1), d2(n + 1); for (u32 i = 0; i < n; ++i, std::swap(d, d2)) - for (std::fill_n(d.begin(), n, INF); auto [w, u, v] : edges) d[v] = std::min(d[v], d2[u] + w); + for (fill_n(d.begin(), n, INF); auto [w, u, v] : edges) d[v] = min(d[v], d2[u] + w); vec dn = d2, mx(n + 1); T ans = INF; - std::ranges::transform(dn, mx.begin(), [&](auto x) NE { return x / n; }); - std::ranges::fill(d2, 0); + transform(dn, mx.begin(), [&](auto x) NE { return x / n; }); + fill(d2, 0); for (u32 i = 1; i < n; ++i, std::swap(d, d2)) { - for (std::fill_n(d.begin(), n, INF); auto [w, u, v] : edges) d[v] = std::min(d[v], d2[u] + w); - flt_ (u32, j, 0, n) mx[j] = std::max(mx[j], (dn[j] - d[j]) / (n - i)); + for (fill_n(d.begin(), n, INF); auto [w, u, v] : edges) d[v] = min(d[v], d2[u] + w); + flt_ (u32, j, 0, n) mx[j] = max(mx[j], (dn[j] - d[j]) / (n - i)); } flt_ (u32, i, 0, n) - if (dn[i] < INF) ans = std::min(ans, mx[i]); + if (dn[i] < INF) ans = min(ans, mx[i]); return ans; } diff --git a/src/code/graph/path.hpp b/src/code/graph/path.hpp index c20da0df8..0e3a3eddf 100644 --- a/src/code/graph/path.hpp +++ b/src/code/graph/path.hpp @@ -5,14 +5,14 @@ namespace tifa_libs::graph { -template +template CEXP std::optional path(G CR g, u32 from, u32 to) NE { vecu ret; bool failed = true; auto dfs = [&](auto &&dfs, u32 now, u32 fa) NE -> void { ret.push_back(now); if (now == to) return void(failed = false); - if CEXP (adjlistw_c) + if CEXP (alistw_c) for (auto &&[v, w] : g[now]) { u32 to = 0; if ((to = v) == fa) continue; diff --git a/src/code/graph/ringcnt4.hpp b/src/code/graph/ringcnt4.hpp index b65663cb9..e6f9587d0 100644 --- a/src/code/graph/ringcnt4.hpp +++ b/src/code/graph/ringcnt4.hpp @@ -6,7 +6,7 @@ namespace tifa_libs::graph { namespace ringcnt4_impl_ { template -requires(adjlist_c && !adjlistw_c) +requires(alist_c && !alistw_c) CEXP u64 run(G CR dg, G CR dgv) NE { const u32 n = dg.size(); u64 ans = 0; @@ -32,7 +32,7 @@ CEXP u64 run(G CR dg, G CR dgv) NE { //! should be simple undirected graph template -requires(adjlist_c && !adjlistw_c) +requires(alist_c && !alistw_c) CEXP u64 ringcnt4(G CR g) NE { const u32 n = g.size(); G dg(n), dgv(n); diff --git a/src/code/graph/ringenum3.hpp b/src/code/graph/ringenum3.hpp index 152f94ecc..405376a4b 100644 --- a/src/code/graph/ringenum3.hpp +++ b/src/code/graph/ringenum3.hpp @@ -7,7 +7,7 @@ namespace tifa_libs::graph { namespace ringenum3_impl_ { template -requires(adjlist_c && !adjlistw_c) +requires(alist_c && !alistw_c) CEXP void run(G CR dg, F&& func) NE { const u32 n = dg.size(); vecb vis(n); diff --git a/src/code/graph/sat2.hpp b/src/code/graph/sat2.hpp index 506d3194c..a2504238d 100644 --- a/src/code/graph/sat2.hpp +++ b/src/code/graph/sat2.hpp @@ -21,10 +21,10 @@ class sat2 { } // @return a, a_i == 1 if c_i is true else a_i == 0 CEXP std::optional solve() NE { - std::inclusive_scan(st.begin(), st.end(), st.begin()), *std::move_backward(st.begin(), st.end() - 1, st.end()) = 0; + std::inclusive_scan(st.begin(), st.end(), st.begin()), *move_backward(st.begin(), st.end() - 1, st.end()).out = 0; vecu to(e.size()); for (auto CR[u, v] : e) to[st[u]++] = v; - *std::move_backward(st.begin(), st.end() - 1, st.end()) = 0; + *move_backward(st.begin(), st.end() - 1, st.end()).out = 0; vecu ans(n, -1_u32), lst; auto f = [&](auto &&f, u32 v) NE -> bool { lst.push_back(v / 2), ans[v / 2] = v & 1; diff --git a/src/code/graph/steiner_tree.hpp b/src/code/graph/steiner_tree.hpp index 8b37107bf..0c5824521 100644 --- a/src/code/graph/steiner_tree.hpp +++ b/src/code/graph/steiner_tree.hpp @@ -6,7 +6,7 @@ namespace tifa_libs::graph { -template +template class steiner_tree { G CR e; vecu CR a; diff --git a/src/code/graph/topo_sort.hpp b/src/code/graph/topo_sort.hpp index a4eb264c6..e9b9d90da 100644 --- a/src/code/graph/topo_sort.hpp +++ b/src/code/graph/topo_sort.hpp @@ -7,7 +7,7 @@ namespace tifa_libs::graph { //! return empty vector if @g is not DAG template -requires(adjlist_c && !adjlistw_c) +requires(alist_c && !alistw_c) CEXP vecu topo_sort(G CR g) NE { const u32 n = g.size(); vecb vis(n), _(n); @@ -23,7 +23,7 @@ CEXP vecu topo_sort(G CR g) NE { }; flt_ (u32, i, 0, n) if (!vis[i] && !dfs(dfs, i)) return {}; - std::ranges::reverse(ans); + reverse(ans); return ans; } diff --git a/src/code/graph/v_bcc.hpp b/src/code/graph/v_bcc.hpp index bd5d47004..0ad17868a 100644 --- a/src/code/graph/v_bcc.hpp +++ b/src/code/graph/v_bcc.hpp @@ -1,47 +1,61 @@ #ifndef TIFALIBS_GRAPH_V_BCC #define TIFALIBS_GRAPH_V_BCC -#include "../util/util.hpp" +#include "alist.hpp" namespace tifa_libs::graph { -template -class v_bcc { - vvec CR g; - - public: - u32 id; +template +struct v_bcc { + static_assert(!get_ecut || (!get_vcut && !get_belongs)); vecu dfn, low; - vecb cut; vvecu belongs; + vecb vcut; + vecptu ecut; - //! EW need rev_edge - CEXPE v_bcc(cT_(vvec) G) NE : g(G) { build(); } - - CEXP void build() NE { - u32 cnt = 0, n = u32(g.size()); - id = 0, dfn = low = vecu(n, n), cut = vecb(n, 0); - vecu s; - auto dfs = [&](auto &&dfs, u32 u, u32 fa, u32 inv_from) NE -> void { - dfn[u] = low[u] = cnt++; - if (u == fa && g[u].size() == 0) cut[u] = 1, belongs.push_back(vecu(1, u)), ++id; - s.push_back(u); - flt_ (u32, i, 0, (u32)g[u].size()) { - auto v = g[u][i]; - if (v.to == fa && i == inv_from) continue; - if (dfn[v.to] == n) { - if (dfs(dfs, v.to, u, v.inv), low[u] = min(low[u], low[v.to]); low[v.to] >= dfn[u]) { - u32 p; - cut[u] = 1, belongs.push_back(vecu(1, u)); - do p = s.back(), s.pop_back(), belongs[id].push_back(p); - while (p != v.to); - ++id; + //! g should be undirect + template + CEXP v_bcc(alist CR g) NE : dfn(g.size()), low(g.size()) { + if CEXP (get_vcut) vcut = vecb(g.size()); + if CEXP (get_ecut) ecut.reserve(g.size()); + vecu stk; + u32 cnt = 0, start; + auto tarjan = [&](auto&& f, u32 u, u32 fa) -> void { + u32 son = 0; + bool ecut_flag = false; + low[u] = dfn[u] = ++cnt; + if CEXP (get_belongs) stk.push_back(u); + for (auto v : g[u]) + if (!dfn[v]) { + ++son, f(f, v, u), low[u] = min(low[u], low[v]); + if CEXP (get_ecut) { + if (low[v] > dfn[u]) ecut.emplace_back(v, u); + } else { + if (low[v] >= dfn[u]) { + if CEXP (get_vcut) + if (u != start) vcut[u] = true; + if CEXP (get_belongs) { + vecu res; + u32 p; + do res.push_back(p = stk.back()), stk.pop_back(); + while (v != p); + res.push_back(u), belongs.emplace_back(std::move(res)); + } + } } - } else low[u] = min(low[u], dfn[v.to]); - } + } else { + if CEXP (get_ecut) { + if (v != fa || ecut_flag) low[u] = min(low[u], dfn[v]); + else ecut_flag = true; + } else if (v != fa) low[u] = min(low[u], dfn[v]); + } + if CEXP (get_vcut) + if (u == start && son >= 2) vcut[u] = true; + if CEXP (get_belongs) + if (!~fa && !son) belongs.push_back({u}); }; - flt_ (u32, i, 0, n) - if (dfn[i] == n) dfs(dfs, i, i, -1_u32); + flt_ (u32, i, 0, g.size()) + if (!dfn[i]) tarjan(tarjan, start = i, -1_u32); } }; diff --git a/src/code/io/fastin.hpp b/src/code/io/fastin.hpp index 03a837cac..7594a9fcf 100644 --- a/src/code/io/fastin.hpp +++ b/src/code/io/fastin.hpp @@ -90,7 +90,7 @@ class fastin { SKIP(ndigit, !isdigit) #undef SKIP template - requires(std::integral && !char_c) + requires(imost64_c && !char_c) fastin &operator>>(T &n) NE { if CEXP (std::same_as) n = skip_ndigit().get() != '0'; else { diff --git a/src/code/io/fastout.hpp b/src/code/io/fastout.hpp index efd5e400f..daa106c0d 100644 --- a/src/code/io/fastout.hpp +++ b/src/code/io/fastout.hpp @@ -36,23 +36,23 @@ class fastout { fastout &operator<<(strn CR str) NE { return *this << str.c_str(); } fastout &operator<<(strnv str) NE { return write_str(str.data(), str.size()); } template - requires(sint_c && !char_c && sizeof(T) <= 8) + requires(smost64_c && !char_c) fastout &operator<<(T n) NE { if (n < 0) (*this << '-'), n = -n; return *this << to_uint_t(n); } template - requires(uint_c && !char_c && sizeof(T) <= 8) + requires(umost64_c && !char_c) fastout &operator<<(T n) NE { if CEXP (std::same_as) return *this << (char(n | '0')); else { auto res = std::to_chars(int_buf, int_buf + INTBUF, n); - return write_str(int_buf, res.ptr - int_buf); + return write_str(int_buf, usz(res.ptr - int_buf)); } } fastout &operator<<(std::floating_point auto n) NE { auto res = std::to_chars(int_buf, int_buf + INTBUF, n, fmt, precision); - return write_str(int_buf, res.ptr - int_buf); + return write_str(int_buf, usz(res.ptr - int_buf)); } fastout &setf(std::chars_format f) NE { fmt = f; diff --git a/src/code/lalg/det_rd_mat.hpp b/src/code/lalg/det_rd_mat.hpp index b8f333da2..893d0ca9b 100644 --- a/src/code/lalg/det_rd_mat.hpp +++ b/src/code/lalg/det_rd_mat.hpp @@ -16,7 +16,7 @@ auto det_rd(Mat mat, Gn &gen, Is0 &&is0) NE { assert(n == mat.col()); auto gen2 = [&gen](u32 n) NE { vec v(n); - std::ranges::generate(v, gen); + generate(v, gen); return v; }; vec u = gen2(n), v = gen2(n), diag = gen2(n), _(n * 2); diff --git a/src/code/lalg/ge_bmat.hpp b/src/code/lalg/ge_bmat.hpp index 6a64e7828..3443c7bb3 100644 --- a/src/code/lalg/ge_bmat.hpp +++ b/src/code/lalg/ge_bmat.hpp @@ -18,7 +18,7 @@ CEXP u32 ge_bmat(bitmat &bmat, bool clear_u = true) NE { break; } if (i2 != i) swap(bmat[i2], bmat[i]); - else std::stable_sort(bmat.begin() + i, bmat.end(), [](auto CR l, auto CR r) NE { return l._Find_first() > r._Find_first(); }); + else stable_sort(bmat.begin() + i, bmat.end(), [](auto CR l, auto CR r) NE { return l._Find_first() > r._Find_first(); }); if (!bmat[i][c] && (c = (u32)bmat[i]._Find_next(c)) == C) break; } flt_ (u32, j, clear_u ? 0 : i + 1, R) diff --git a/src/code/lalg/ge_mat.hpp b/src/code/lalg/ge_mat.hpp index 1d1ec8bd3..bfcd9ee3d 100644 --- a/src/code/lalg/ge_mat.hpp +++ b/src/code/lalg/ge_mat.hpp @@ -6,7 +6,7 @@ namespace tifa_libs::math { -template > +template > requires(!euclid || !std::is_floating_point_v) && requires(Is0 is0, T t) { { is0(t) } -> std::same_as; } @@ -16,7 +16,7 @@ CEXP i32 ge_mat(matrix& mat, Is0 is0, bool clear_u = true) NE { bool neg = false; auto swapr = [&](u32 i, u32 c) NE { auto ir = mat.data().begin() + i, - ir2 = std::max_element(ir, mat.data().end(), [&](auto CR l, auto CR r) NE { + ir2 = max_element(ir, mat.data().end(), [&](auto CR l, auto CR r) NE { flt_ (u32, i, c, C) if (l[i] != r[i]) return l[i] < r[i]; return false; diff --git a/src/code/lalg/mat.hpp b/src/code/lalg/mat.hpp index 3cea54670..928855a56 100644 --- a/src/code/lalg/mat.hpp +++ b/src/code/lalg/mat.hpp @@ -51,7 +51,7 @@ class matrix { CEXP matrix submat(u32 row_l, u32 row_r, u32 col_l, u32 col_r) CNE { assert(row_l < row_r && row_r <= row() && col_l < col_r && col_r <= col()); matrix ret(row_r - row_l, col_r - col_l); - FOR1_ (i, row_l, row_r) std::copy(d[i].begin() + col_l, d[i].begin() + col_r, ret.d[i - row_l].begin()); + FOR1_ (i, row_l, row_r) copy(d[i].begin() + col_l, d[i].begin() + col_r, ret.d[i - row_l].begin()); return ret; } CEXP void swap_row(u32 r1, u32 r2) NE { @@ -88,7 +88,7 @@ class matrix { CEXP matrix &operator*=(cT_(T) v) NE { if CEXP (std::is_same_v) { if (!v) - for (auto &i : d) std::ranges::fill(i, false); + for (auto &i : d) fill(i, false); return *this; } else apply([&v](u32, u32, T &val) NE { val *= v; }); return *this; diff --git a/src/code/lalg/matsp.hpp b/src/code/lalg/matsp.hpp index 8c2135d54..d0af065d0 100644 --- a/src/code/lalg/matsp.hpp +++ b/src/code/lalg/matsp.hpp @@ -34,9 +34,9 @@ class matsp { return T{}; } CEXP void shrink_row(u32 r) NE { - d[r].erase(std::remove_if(d[r].begin(), d[r].end(), [](cT_(node) x) NE { return x.second == T{}; }), d[r].end()); + d[r].erase(remove_if(d[r].begin(), d[r].end(), [](cT_(node) x) NE { return x.second == T{}; }), d[r].end()); } - CEXP void sort_row(u32 r) NE { sort(d[r]); } + CEXP void sort_row(u32 r) NE { tifa_libs::sort(d[r]); } template CEXP void apply(F f) NE { flt_ (u32, i, 0, r) @@ -59,7 +59,7 @@ class matsp { l.sort_row(i), r.sort_row(i); auto f1 = l.data().begin(), l1 = l.data().end(), f2 = r.data().begin(), l2 = r.data().end(), d = ret.d[i].begin(); for (; f1 != l1; ++d) { - if (f2 == l2) std::copy(f1, l1, d); + if (f2 == l2) copy(f1, l1, d); if (*f2 < *f1) *d = *f2, ++f2; else if (*f1 < *f2) *d = *f1, ++f1; else { @@ -67,7 +67,7 @@ class matsp { *d = f(i, j, *f1, *f2), ++f1, ++f2; } } - std::copy(f2, l2, d); + copy(f2, l2, d); } return ret; } diff --git a/src/code/lalg/minpoly_rd_mat.hpp b/src/code/lalg/minpoly_rd_mat.hpp index 47d8c98e5..b82ff7175 100644 --- a/src/code/lalg/minpoly_rd_mat.hpp +++ b/src/code/lalg/minpoly_rd_mat.hpp @@ -15,13 +15,13 @@ auto minpoly(Mat CR mat, Gn &gen, Is0 &&is0) NE { assert(n == mat.col()); auto gen2 = [&gen](u32 n) NE { vec v(n); - std::ranges::generate(v, gen); + generate(v, gen); return v; }; vec u = gen2(n), v = gen2(n), _(n * 2); flt_ (u32, i, 0, n * 2) _[i] = std::transform_reduce(u.begin(), u.end(), v.begin(), T{}), v = mat.lproj(v); vec res = lfsr_bm(_, std::forward(is0)); - std::ranges::reverse(res); + reverse(res); return res; } diff --git a/src/code/math/berlekamp_massey.hpp b/src/code/math/berlekamp_massey.hpp index c8ca3651f..0060b4123 100644 --- a/src/code/math/berlekamp_massey.hpp +++ b/src/code/math/berlekamp_massey.hpp @@ -26,7 +26,7 @@ CEXP vec berlekamp_massey(vec CR a) NE { } else flt_ (u32, i, 0, m) c[l - 1 - i] -= d_ * b[m - 1 - i]; } - std::ranges::reverse(c); + reverse(c); return c; } diff --git a/src/code/math/fact_helper.hpp b/src/code/math/fact_helper.hpp index c5c880c70..8403b2662 100644 --- a/src/code/math/fact_helper.hpp +++ b/src/code/math/fact_helper.hpp @@ -16,7 +16,7 @@ struct fact_helper { // ensure fact.size() >= sz static CEXP void ensure(u32 sz = DEFUALT_MAX) NE { - if (sz = std::max(2_u32, std::min((u32)mod(), sz)); sz <= fact.size()) return; + if (sz = max(2_u32, min((u32)mod(), sz)); sz <= fact.size()) return; u32 pre = (u32)fact.size(); fact.resize(sz), ifact.resize(sz); if (pre < 2) pre = 2, fact[0] = fact[1] = ifact[0] = ifact[1] = 1; diff --git a/src/code/math/fact_mint.hpp b/src/code/math/fact_mint.hpp index 6331152f4..9e855d829 100644 --- a/src/code/math/fact_mint.hpp +++ b/src/code/math/fact_mint.hpp @@ -19,7 +19,7 @@ CEXP auto fact_mint(u64 n) NE { g2 = ctsh_fps(g, mint(d * v + v) * iv), g3 = ctsh_fps(g, mint(d * v + d + v) * iv); flt_ (u32, i, 0, (u32)d + 1) g[i] *= g1[i], g2[i] *= g3[i]; - std::copy(g2.begin(), g2.end() - 1, std::back_inserter(g)); + copy(g2.begin(), g2.end() - 1, std::back_inserter(g)); } mint res = 1; u64 i = 0; diff --git a/src/code/math/factl_helper.hpp b/src/code/math/factl_helper.hpp index 49baeb4f7..3616a56b8 100644 --- a/src/code/math/factl_helper.hpp +++ b/src/code/math/factl_helper.hpp @@ -55,7 +55,7 @@ struct factl_helper : fact_helper { } if (B > SZ) { vec g = ctsh_fps(f, val_t(SZ), base_t::ifact, u32(B - SZ)); - std::ranges::move(g, std::back_inserter(f)); + move(g, std::back_inserter(f)); } else f.resize(B); flt_ (u32, i, 0, (u32)B) f[i] *= val_t(i + 1) * SZ; f.insert(f.begin(), 1); diff --git a/src/code/math/isqrt.hpp b/src/code/math/isqrt.hpp index bec03cd36..be746bef2 100644 --- a/src/code/math/isqrt.hpp +++ b/src/code/math/isqrt.hpp @@ -7,7 +7,9 @@ namespace tifa_libs::math { CEXP u32 isqrt(u64 x) NE { if (!x) return 0; +#pragma GCC diagnostic ignored "-Wconversion" const int sh = 31 - (std::bit_width(x) - 1) / 2; +#pragma GCC diagnostic warning "-Wconversion" u32 u = [](u64 x) NE { CEXP u8 TAB[192] = {128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 144, 145, 146, 147, 148, 149, 150, 151, 151, 152, 153, 154, 155, 156, 156, 157, 158, 159, 160, 160, 161, 162, 163, 164, 164, 165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 179, 179, 180, 181, 181, 182, 183, 183, 184, 185, 186, 186, 187, 188, 188, 189, 190, 190, 191, 192, 192, 193, 194, 194, 195, 196, 196, 197, 198, 198, 199, 200, 200, 201, 201, 202, 203, 203, 204, 205, 205, 206, 206, 207, 208, 208, 209, 210, 210, 211, 211, 212, 213, 213, 214, 214, 215, 216, 216, 217, 217, 218, 219, 219, 220, 220, 221, 221, 222, 223, 223, 224, 224, 225, 225, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 232, 232, 233, 233, 234, 234, 235, 235, 236, 237, 237, 238, 238, 239, 239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 246, 246, 247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255, 255}; u32 u = TAB[(x >> 56) - 64]; diff --git a/src/code/util/josephus.hpp b/src/code/math/josephus.hpp similarity index 90% rename from src/code/util/josephus.hpp rename to src/code/math/josephus.hpp index 24f751cf5..57420afb1 100644 --- a/src/code/util/josephus.hpp +++ b/src/code/math/josephus.hpp @@ -1,10 +1,9 @@ -#ifndef TIFALIBS_UTIL_JOSEPHUS -#define TIFALIBS_UTIL_JOSEPHUS +#ifndef TIFALIBS_MATH_JOSEPHUS +#define TIFALIBS_MATH_JOSEPHUS #include "../util/util.hpp" -namespace tifa_libs::util { - +namespace tifa_libs::math { namespace josephus_impl_ { // $O(m)$ CEXP u64 j1(u64 n, u64 k, u64 m) NE { diff --git a/src/code/math/mint.hpp b/src/code/math/mint.hpp index ef2cd1a2b..77438385f 100644 --- a/src/code/math/mint.hpp +++ b/src/code/math/mint.hpp @@ -43,7 +43,7 @@ struct mint : D { friend CEXP mint operator*(mint l, mint CR r) NE { return l *= r; } friend CEXP mint operator/(mint l, mint CR r) NE { return l /= r; } friend CEXP bool operator==(mint CR l, mint CR r) NE { return l.val() == r.val(); } - friend CEXP auto operator<=>(mint CR l, mint CR r) NE { return l.sval() - r.sval(); } + friend CEXP auto operator<=>(mint CR l, mint CR r) NE { return l.sval() <=> r.sval(); } friend auto &operator>>(istream_c auto &is, mint &x) NE { i64 _; is >> _, x = mint(_); diff --git a/src/code/math/mpi.hpp b/src/code/math/mpi.hpp index 8d651f56b..3d4f14a84 100644 --- a/src/code/math/mpi.hpp +++ b/src/code/math/mpi.hpp @@ -3,6 +3,7 @@ #include "../conv/conv_u128.hpp" #include "../fast/str2uint_si64.hpp" +#include "../util/strip.hpp" #include "../util/traits.hpp" namespace tifa_libs::math { @@ -12,8 +13,6 @@ struct mpi : vecu { static_assert(sqrtD * sqrtD == D); private: -#define vec_like std::derived_from auto - struct ict4 { CEXP static auto num = [] { arr num; @@ -28,13 +27,43 @@ struct mpi : vecu { bool neg; +#define vec_like std::derived_from auto + // name starts with u ==> ignore sign + static CEXP auto ucmp(vec_like CR a, vec_like CR b) NE { + if (a.size() != b.size()) return a.size() <=> b.size(); + return std::lexicographical_compare_three_way(a.rbegin(), a.rend(), b.rbegin(), b.rend()); + } + static CEXP auto cmp(mpi CR a, mpi CR b) NE { + if (a.neg) return b.neg ? ucmp(b, a) : std::strong_ordering::less; + return b.neg ? std::strong_ordering::greater : ucmp(a, b); + } + static CEXP bool is_0(vec_like CR a) NE { return a.empty(); } + static CEXP bool is_pm1(vec_like CR a) NE { return a.size() == 1 && a[0] == 1; } + static CEXP bool is_1(mpi CR a) NE { return !a.neg && is_pm1(a); } + static CEXP void shrink_(vec_like& a) NE { + auto [_, r] = rstrip_view(a, [](u32 x) { return !x; }); + a.erase(r, a.end()); + } + template + static CEXP vecu int2vecu(T x) NE { + if CEXP (sint_c) assert(x >= 0); + vecu res; + while (x) res.push_back((u32)(x % D)), x /= D; + return res; + } + static CEXP i64 uvec2i64(vec_like CR a) NE { + i64 res = 0; + for (u32 i = (u32)a.size() - 1; ~i; --i) res = res * D + a[i]; + return res; + } + public: CEXPE mpi() NE : vecu(), neg{false} {} CEXP mpi(bool n, itlu x) NE : vecu(x), neg(n) {} CEXP mpi(bool n, spnu d) NE : vecu(d.begin(), d.end()), neg(n) {} template CEXP mpi(T x) NE : mpi() { - if CEXP (is_sint_v) + if CEXP (sint_c) if (x < 0) neg = true, x = -x; while (x) push_back(u32(to_uint_t(x) % D)), x /= (T)D; } @@ -59,24 +88,31 @@ struct mpi : vecu { CEXP void set_neg(bool s) NE { neg = s; } CEXP bool is_neg() CNE { return neg; } + CEXP bool is_zero() CNE { return is_0(*this); } + CEXP void shrink() NE { shrink_(*this); } + friend CEXP mpi abs(mpi m) NE { + m.neg = false; + return m; + } + friend CEXP mpi operator+(mpi CR l, mpi CR r) NE { - if (l.neg == r.neg) return {l.neg, add_(l, r)}; - if (leq_(l, r)) { - auto c = sub_(r, l); - return {is0_(c) ? false : r.neg, c}; + if (l.neg == r.neg) return {l.neg, uadd(l, r)}; + if (std::is_lteq(ucmp(l, r))) { + auto c = usub(r, l); + return {is_0(c) ? false : r.neg, c}; } - auto c = sub_(l, r); - return {is0_(c) ? false : l.neg, c}; + auto c = usub(l, r); + return {is_0(c) ? false : l.neg, c}; } friend CEXP mpi operator-(mpi CR l, mpi CR r) NE { return l + (-r); } friend CEXP mpi operator*(mpi CR l, mpi CR r) NE { - auto c = mul_(l, r); - bool n = is0_(c) ? false : (l.neg ^ r.neg); + auto c = umul(l, r); + bool n = is_0(c) ? false : (l.neg ^ r.neg); return {n, c}; } friend CEXP ptt divmod(mpi CR l, mpi CR r) NE { - auto dm = divmod_newton_(l, r); - return {mpi{is0_(dm.first) ? false : l.neg != r.neg, dm.first}, mpi{is0_(dm.second) ? false : l.neg, dm.second}}; + auto dm = udivmod(l, r); + return {mpi{is_0(dm.first) ? false : l.neg != r.neg, dm.first}, mpi{is_0(dm.second) ? false : l.neg, dm.second}}; } friend CEXP mpi operator/(mpi CR l, mpi CR r) NE { return divmod(l, r).first; } friend CEXP mpi operator%(mpi CR l, mpi CR r) NE { return divmod(l, r).second; } @@ -92,16 +128,9 @@ struct mpi : vecu { return ret; } CEXP mpi operator+() CNE { return *this; } - friend CEXP mpi abs(mpi m) NE { - m.neg = false; - return m; - } - CEXP bool is_zero() CNE { return is0_(*this); } - friend CEXP bool operator==(mpi CR l, mpi CR r) NE { return l.neg == r.neg && l == r; } - // clang-format off - friend CEXP auto operator<=>(mpi CR l, mpi CR r) NE { return l == r ? 0 : neq_lt_(l, r) ? -1 : 1; } - // clang-format on - CEXP void shrink() NE { shrink_(*this); } + friend CEXP auto operator<=>(mpi CR l, mpi CR r) NE { return cmp(l, r); } + friend CEXP bool operator==(mpi CR l, mpi CR r) NE { return std::is_eq(l <=> r); } + CEXP strn to_str() CNE { if (is_zero()) return "0"; strn r; @@ -114,7 +143,7 @@ struct mpi : vecu { return r; } CEXP i64 to_i64() CNE { - i64 res = to_i64_(*this); + i64 res = uvec2i64(*this); if (neg) res = -res; return res; } @@ -132,24 +161,7 @@ struct mpi : vecu { friend auto& operator<<(ostream_c auto& os, mpi CR m) NE { return os << m.to_str(); } private: - static CEXP bool lt_(vec_like CR a, vec_like CR b) NE { - if (a.size() != b.size()) return a.size() < b.size(); - for (u32 i = (u32)a.size() - 1; ~i; --i) - if (a[i] != b[i]) return a[i] < b[i]; - return false; - } - static CEXP bool leq_(vec_like CR a, vec_like CR b) NE { return a == b || lt_(a, b); } - // a < b (s.t. a != b) - static CEXP bool neq_lt_(mpi CR l, mpi CR r) NE { - if (assert(l != r); l.neg != r.neg) return l.neg; - return lt_(l, r) ^ l.neg; - } - static CEXP bool is0_(vec_like CR a) NE { return a.empty(); } - static CEXP bool is1_(vec_like CR a) NE { return a.size() == 1 && a[0] == 1; } - static CEXP void shrink_(vec_like& a) NE { - while (a.size() && !a.back()) a.pop_back(); - } - static CEXP vecu add_(vec_like CR a, vec_like CR b) NE { + static CEXP vecu uadd(vec_like CR a, vec_like CR b) NE { vecu c(max(a.size(), b.size()) + 1); flt_ (u32, i, 0, (u32)a.size()) c[i] += a[i]; flt_ (u32, i, 0, (u32)b.size()) c[i] += b[i]; @@ -158,8 +170,8 @@ struct mpi : vecu { shrink_(c); return c; } - static CEXP vecu sub_(vec_like CR a, vec_like CR b) NE { - assert(leq_(b, a)); + static CEXP vecu usub(vec_like CR a, vec_like CR b) NE { + assert(std::is_lteq(ucmp(b, a))); vecu c = a; u32 borrow = 0; flt_ (u32, i, 0, (u32)a.size()) { @@ -170,7 +182,7 @@ struct mpi : vecu { shrink_(c); return c; } - static CEXP vecu mul_3ntt_(vec_like CR a, vec_like CR b) NE { + static CEXP vecu umul_3ntt(vec_like CR a, vec_like CR b) NE { if (a.empty() || b.empty()) return {}; auto m = conv_u128(a, b); vecu c; @@ -184,7 +196,7 @@ struct mpi : vecu { shrink_(c); return c; } - static CEXP vecu mul_bf_(vec_like CR a, vec_like CR b) NE { + static CEXP vecu umul_bf(vec_like CR a, vec_like CR b) NE { if (a.empty() || b.empty()) return {}; vecuu prod(a.size() + b.size() - 1 + 1); flt_ (u32, i, 0, (u32)a.size()) @@ -198,30 +210,30 @@ struct mpi : vecu { shrink_(c); return c; } - static CEXP vecu mul_(vec_like CR a, vec_like CR b) NE { - if (is0_(a) || is0_(b)) return {}; - if (is1_(a)) return b; - if (is1_(b)) return a; - if (min(a.size(), b.size()) <= CONV_NAIVE_THRESHOLD) return a.size() < b.size() ? mul_bf_(b, a) : mul_bf_(a, b); - return mul_3ntt_(a, b); + static CEXP vecu umul(vec_like CR a, vec_like CR b) NE { + if (is_0(a) || is_0(b)) return {}; + if (is_pm1(a)) return b; + if (is_pm1(b)) return a; + if (min(a.size(), b.size()) <= CONV_NAIVE_THRESHOLD) return a.size() < b.size() ? umul_bf(b, a) : umul_bf(a, b); + return umul_3ntt(a, b); } // 0 <= A < 1e16, 1 <= B < 1e8 - static CEXP ptt divmod_li_(vec_like CR a, vec_like CR b) NE { + static CEXP ptt udivmod_li(vec_like CR a, vec_like CR b) NE { assert(a.size() <= 2 && b.size() == 1); - i64 va = to_i64_(a); + i64 va = uvec2i64(a); u32 vb = b[0]; - return {itov_(va / vb), itov_(va % vb)}; + return {int2vecu(va / vb), int2vecu(va % vb)}; } // 0 <= A < 1e16, 1 <= B < 1e16 - static CEXP ptt divmod_ll_(vec_like CR a, vec_like CR b) NE { + static CEXP ptt udivmod_ll(vec_like CR a, vec_like CR b) NE { assert(a.size() <= 2 && b.size() && b.size() <= 2); - i64 va = to_i64_(a), vb = to_i64_(b); - return {itov_(va / vb), itov_(va % vb)}; + i64 va = uvec2i64(a), vb = uvec2i64(b); + return {int2vecu(va / vb), int2vecu(va % vb)}; } // 1 <= B < 1e8 - static CEXP ptt divmod_1e8_(vec_like CR a, vec_like CR b) NE { + static CEXP ptt udivmod_1e8(vec_like CR a, vec_like CR b) NE { if (assert(b.size() == 1); b[0] == 1) return {a, {}}; - if (a.size() <= 2) return divmod_li_(a, b); + if (a.size() <= 2) return udivmod_li(a, b); vecu quo(a.size()); u64 d = 0; u32 b0 = b[0]; @@ -230,32 +242,32 @@ struct mpi : vecu { return {quo, d ? vecu{u32(d)} : vecu{}}; } // 0 <= A, 1 <= B - static CEXP ptt divmod_bf_(vec_like CR a, vec_like CR b) NE { - if (assert(!is0_(b) && b.size()); b.size() == 1) return divmod_1e8_(a, b); - if (max(a.size(), b.size()) <= 2) return divmod_ll_(a, b); - if (lt_(a, b)) return {{}, a}; + static CEXP ptt udivmod_bf(vec_like CR a, vec_like CR b) NE { + if (assert(!is_0(b) && b.size()); b.size() == 1) return udivmod_1e8(a, b); + if (max(a.size(), b.size()) <= 2) return udivmod_ll(a, b); + if (std::is_lt(ucmp(a, b))) return {{}, a}; // B >= 1e8, A >= B u32 norm = D / (b.back() + 1); - vecu x = mul_(a, vecu{norm}), y = mul_(b, vecu{norm}); + vecu x = umul(a, vecu{norm}), y = umul(b, vecu{norm}); u32 yb = y.back(); vecu quo(x.size() - y.size() + 1), rem(x.end() - (int)y.size(), x.end()); for (u32 i = (u32)quo.size() - 1; ~i; --i) { if (rem.size() == y.size()) { - if (leq_(y, rem)) quo[i] = 1, rem = sub_(rem, y); + if (std::is_lteq(ucmp(y, rem))) quo[i] = 1, rem = usub(rem, y); } else if (rem.size() > y.size()) { assert(y.size() + 1 == rem.size()); u32 q = (u32)(((u64)rem[rem.size() - 1] * D + rem[rem.size() - 2]) / yb); - vecu yq = mul_(y, vecu{q}); - while (lt_(rem, yq)) --q, yq = sub_(yq, y); - rem = sub_(rem, yq); - while (leq_(y, rem)) ++q, rem = sub_(rem, y); + vecu yq = umul(y, vecu{q}); + while (std::is_lt(ucmp(rem, yq))) --q, yq = usub(yq, y); + rem = usub(rem, yq); + while (std::is_lteq(ucmp(y, rem))) ++q, rem = usub(rem, y); quo[i] = q; } if (i) rem.insert(rem.begin(), x[i - 1]); } shrink_(quo), shrink_(rem); - auto [q2, r2] = divmod_1e8_(rem, vecu{norm}); - assert(is0_(r2)); + auto [q2, r2] = udivmod_1e8(rem, vecu{norm}); + assert(is_0(r2)); return {quo, q2}; } // 1 / a, abserr = B^{-deg} @@ -264,49 +276,38 @@ struct mpi : vecu { u32 k = deg, c = (u32)a.size(); while (k > 64) k = (k + 1) / 2; vecu z(c + k + 1); - z.back() = 1, z = divmod_bf_(z, a).first; + z.back() = 1, z = udivmod_bf(z, a).first; while (k < deg) { - vecu s = mul_(z, z); + vecu s = umul(z, z); s.insert(s.begin(), 0); u32 d = min(c, 2 * k + 1); - vecu t{a.end() - d, a.end()}, u = mul_(s, t); + vecu t{a.end() - d, a.end()}, u = umul(s, t); u.erase(u.begin(), u.begin() + d); - vecu w(k + 1), w2 = add_(z, z); - std::ranges::copy(w2, std::back_inserter(w)); - (z = sub_(w, u)).erase(z.begin()), k *= 2; + vecu w(k + 1), w2 = uadd(z, z); + copy(w2, std::back_inserter(w)); + (z = usub(w, u)).erase(z.begin()), k *= 2; } z.erase(z.begin(), z.begin() + k - deg); return z; } - static CEXP ptt divmod_newton_(vec_like CR a, vec_like CR b) NE { - if (assert(!is0_(b)); b.size() <= 64) return divmod_bf_(a, b); - if ((int)(a.size() - b.size()) <= 64) return divmod_bf_(a, b); + static CEXP ptt udivmod(vec_like CR a, vec_like CR b) NE { + if (assert(!is_0(b)); b.size() <= 64) return udivmod_bf(a, b); + if ((int)(a.size() - b.size()) <= 64) return udivmod_bf(a, b); u32 norm = D / (b.back() + 1); - vecu x = mul_(a, vecu{norm}), y = mul_(b, vecu{norm}); + vecu x = umul(a, vecu{norm}), y = umul(b, vecu{norm}); u32 s = (u32)x.size(), t = (u32)y.size(), deg = s + 2 - t; - vecu z = inv_(y, deg), q = mul_(x, z); + vecu z = inv_(y, deg), q = umul(x, z); q.erase(q.begin(), q.begin() + t + deg); - vecu yq = mul_(y, vecu{q}); - while (lt_(x, yq)) q = sub_(q, vecu{1}), yq = sub_(yq, y); - vecu r = sub_(x, yq); - while (leq_(y, r)) q = add_(q, vecu{1}), r = sub_(r, y); + vecu yq = umul(y, vecu{q}); + while (std::is_lt(ucmp(x, yq))) q = usub(q, vecu{1}), yq = usub(yq, y); + vecu r = usub(x, yq); + while (std::is_lteq(ucmp(y, r))) q = uadd(q, vecu{1}), r = usub(r, y); shrink_(q), shrink_(r); - auto [q2, r2] = divmod_1e8_(r, vecu{norm}); - assert(is0_(r2)); + auto [q2, r2] = udivmod_1e8(r, vecu{norm}); + assert(is_0(r2)); return {q, q2}; } - template - static CEXP vecu itov_(T x) NE { - if CEXP (is_sint_v) assert(x >= 0); - vecu res; - while (x) res.push_back((u32)(x % D)), x /= D; - return res; - } - static CEXP i64 to_i64_(vec_like CR a) NE { - i64 res = 0; - for (u32 i = (u32)a.size() - 1; ~i; --i) res = res * D + a[i]; - return res; - } + #undef vec_like }; diff --git a/src/code/math/youngt.hpp b/src/code/math/youngt.hpp index 51ac94b3d..d9254a7ed 100644 --- a/src/code/math/youngt.hpp +++ b/src/code/math/youngt.hpp @@ -36,7 +36,7 @@ class Youngt { CEXP void insert(u32 val) NE { ++n; for (auto& i : d) { - auto it = std::ranges::lower_bound(i, val); + auto it = lower_bound(i, val); if (it == i.end()) return i.push_back(val); swap(val, *it); } diff --git a/src/code/nt/exgcd.hpp b/src/code/nt/exgcd.hpp index 0fd8a7954..7931703f4 100644 --- a/src/code/nt/exgcd.hpp +++ b/src/code/nt/exgcd.hpp @@ -47,7 +47,7 @@ CEXP auto exgcd_b(U a, U b) NE { template CEXP auto exgcd(T a, T b) NE { using U = to_uint_t; - if (auto [x, y] = std::minmax(a, b); x >= 0 && y <= T(U(-1) >> sizeof(U))) return exgcd_b((U)a, (U)b); + if (auto [x, y] = minmax(a, b); x >= 0 && y <= T(U(-1) >> sizeof(U))) return exgcd_b((U)a, (U)b); if CEXP (only_x) { T s = 1, u = 0; while (b) { diff --git a/src/code/nt/lcm.hpp b/src/code/nt/lcm.hpp index d9e87799c..554ed4dd3 100644 --- a/src/code/nt/lcm.hpp +++ b/src/code/nt/lcm.hpp @@ -10,7 +10,7 @@ CEXP std::common_type_t lcm(T a, U b) NE { using V = std::common_type_t; using W = to_uint_t; if (!a || !b) return 0; - auto [v, u] = std::minmax(a = abs(a), b = abs(b)); + auto [v, u] = minmax(a = abs(a), b = abs(b)); return u / (V)gcd_impl_::gcd__(u, v) * v; } diff --git a/src/code/nt/lsieve.hpp b/src/code/nt/lsieve.hpp index ae6d6c95d..1d13fa9c9 100644 --- a/src/code/nt/lsieve.hpp +++ b/src/code/nt/lsieve.hpp @@ -13,7 +13,7 @@ struct lsieve : Ts... { CEXPE lsieve(u32 n) NE : Ts(n)..., not_prime(n) { if (n < 2) return; // clang-format off - primes.reserve((usz)std::max(127, int(n * (n >= 2e5 ? 1.6 : 1.7) / std::bit_width(n) + 1))); + primes.reserve((usz)max(127, int(n * (n >= 2e5 ? 1.6 : 1.7) / std::bit_width(n) + 1))); // clang-format on flt_ (u32, i, 2, n) { if (!not_prime[i]) primes.push_back(i), (..., Ts::prime(i)); diff --git a/src/code/nt/norm_fact.hpp b/src/code/nt/norm_fact.hpp index b4211f1da..7a2c1e8b3 100644 --- a/src/code/nt/norm_fact.hpp +++ b/src/code/nt/norm_fact.hpp @@ -65,7 +65,7 @@ CEXP vecptuu norm_fact(u64 n) NE { vecptuu ans; for (auto& g : norm_fact_impl_::nf(n)) if (ans.emplace_back(g.real(), g.imag()); !g.imag()) ans.emplace_back(g.imag(), g.real()); - std::ranges::sort(ans); + tifa_libs::sort(ans); return ans; } diff --git a/src/code/nt/pfactors.hpp b/src/code/nt/pfactors.hpp index 976890766..05c63b1ff 100644 --- a/src/code/nt/pfactors.hpp +++ b/src/code/nt/pfactors.hpp @@ -49,7 +49,7 @@ CEXP vecuu pfactors(u64 n) NE { if (n < 2) return p; pfactors_impl_::run(n, p); if CEXP (unique) return uniq(p); - std::ranges::sort(p); + tifa_libs::sort(p); return p; } CEXP vecp pf_exp(u64 n) NE { diff --git a/src/code/opt/alpha_beta.hpp b/src/code/opt/alpha_beta.hpp index 60516865a..37181cbb3 100644 --- a/src/code/opt/alpha_beta.hpp +++ b/src/code/opt/alpha_beta.hpp @@ -7,7 +7,7 @@ namespace tifa_libs::opt { template -CEXP T alpha_beta(cT_(graph::tree) tr, vec CR v_weight) NE { +CEXP T alpha_beta(graph::tree CR tr, vec CR v_weight) NE { auto dfs = [&](auto &&dfs, u32 u, T a, T b, bool is_max = 1) NE -> T { if (tr.g[u].empty()) return v_weight[u]; if (is_max) { diff --git a/src/code/opt/astar.hpp b/src/code/opt/astar.hpp index 836bbad5d..d58d701d7 100644 --- a/src/code/opt/astar.hpp +++ b/src/code/opt/astar.hpp @@ -1,14 +1,14 @@ #ifndef TIFALIBS_OPT_ASTAR #define TIFALIBS_OPT_ASTAR -#include "../util/traits.hpp" +#include "../util/util.hpp" namespace tifa_libs::opt { template requires requires(T x, T y) { { x.solved() } -> std::same_as; - { x.next() } -> iterable_c; + { x.next() } -> range; x.cost() < y.cost(); x < y; } diff --git a/src/code/util/dlx.hpp b/src/code/opt/dlx.hpp similarity index 95% rename from src/code/util/dlx.hpp rename to src/code/opt/dlx.hpp index e0bebd985..1b4776147 100644 --- a/src/code/util/dlx.hpp +++ b/src/code/opt/dlx.hpp @@ -1,9 +1,9 @@ -#ifndef TIFALIBS_UTIL_DLX -#define TIFALIBS_UTIL_DLX +#ifndef TIFALIBS_OPT_DLX +#define TIFALIBS_OPT_DLX -#include "util.hpp" +#include "../util/util.hpp" -namespace tifa_libs::util { +namespace tifa_libs::opt { class DLX { struct node { @@ -97,6 +97,6 @@ class DLX { #undef dlxfor_ }; -} // namespace tifa_libs::util +} // namespace tifa_libs::opt #endif \ No newline at end of file diff --git a/src/code/opt/heuristic_lbsa.hpp b/src/code/opt/heuristic_lbsa.hpp index ed5209dbf..25f25ccfe 100644 --- a/src/code/opt/heuristic_lbsa.hpp +++ b/src/code/opt/heuristic_lbsa.hpp @@ -39,10 +39,10 @@ class heuristic_lbsa { } private: - static CEXP void inv_(TPN Cont::iterator l, TPN Cont::iterator r) NE { std::reverse(l, std::next(r)); } + static CEXP void inv_(TPN Cont::iterator l, TPN Cont::iterator r) NE { reverse(l, std::next(r)); } static CEXP void ins_(TPN Cont::iterator l, TPN Cont::iterator r) NE { auto x = *r; - std::move_backward(l, r, std::next(r)), *l = x; + move_backward(l, r, std::next(r)), *l = x; } static CEXP void swap_(TPN Cont::iterator l, TPN Cont::iterator r) NE { std::iter_swap(l, r); } std::pair gen() NE { diff --git a/src/code/opt/lcs_circ.hpp b/src/code/opt/lcs_circ.hpp index 93d8b81ef..e2f984bcd 100644 --- a/src/code/opt/lcs_circ.hpp +++ b/src/code/opt/lcs_circ.hpp @@ -1,14 +1,14 @@ #ifndef TIFALIBS_OPT_LCS_CIRC #define TIFALIBS_OPT_LCS_CIRC -#include "../util/traits.hpp" +#include "../util/util.hpp" namespace tifa_libs::opt { -template +template CEXP u32 lcs_circ(cT_(T) a, cT_(T) b) NE { T b_(b.size() * 2); - std::ranges::copy(b, b_.begin()), std::ranges::copy(b, std::back_inserter(b_)); + copy(b, b_.begin()), copy(b, std::back_inserter(b_)); vvecb left(a.size() + 1, vecb(b_.size() + 1)), up = left; auto f = [&](u32 x, u32 y) NE { assert(x && y); diff --git a/src/code/opt/lis.hpp b/src/code/opt/lis.hpp index 76cf4d41a..104ce2362 100644 --- a/src/code/opt/lis.hpp +++ b/src/code/opt/lis.hpp @@ -11,7 +11,7 @@ CEXP vecu lis(vec CR a, T inf = std::numeric_limits::max(), C&& comp = C{} vec f{inf}; vecu g; for (auto i : a) { - auto it = std::ranges::lower_bound(f, i, comp); + auto it = lower_bound(f, i, comp); g.push_back(u32(it - f.begin())); if (it == f.end()) f.push_back(i); else *it = i; @@ -20,7 +20,7 @@ CEXP vecu lis(vec CR a, T inf = std::numeric_limits::max(), C&& comp = C{} vecu ret; for (u32 i = u32(g.size() - 1), now = u32(f.size() - 1); ~i; --i) if (g[i] == now && val > a[i]) ret.push_back((u32)i), --now, val = a[i]; - std::ranges::reverse(ret); + reverse(ret); return ret; } diff --git a/src/code/opt/tsearch.hpp b/src/code/opt/tsearch.hpp index b9d551309..6f1e0d9fd 100644 --- a/src/code/opt/tsearch.hpp +++ b/src/code/opt/tsearch.hpp @@ -16,7 +16,7 @@ CEXP auto tsearch(I l, I r, F&& f) NE { fml = f(ml = l + (r - l) * (1 - std::numbers::phi_v)); fmr = f(mr = r - (r - l) * (1 - std::numbers::phi_v)); do { - if CEXP (is_int_v) { + if CEXP (int_c) { if (r - l < 8) { I x = l, fx = fl; if (fr < fx) x = r, fx = fr; diff --git a/src/code/poly/comp_fps.hpp b/src/code/poly/comp_fps.hpp index 78d6a0993..3cbfcbcdb 100644 --- a/src/code/poly/comp_fps.hpp +++ b/src/code/poly/comp_fps.hpp @@ -20,7 +20,7 @@ CEXP auto comp_fps(poly f, poly g) N return a; } vec bb(k * h * 4), cc(k * h * 2); - flt_ (u32, i, 0, k) std::copy(b.begin() + i * h, b.begin() + i * h + n + 1, bb.begin() + i * h * 2); + flt_ (u32, i, 0, k) copy(b.begin() + i * h, b.begin() + i * h + n + 1, bb.begin() + i * h * 2); bb[k * h * 2] += 1, core4.dif(bb); for (u32 i = 0; i < k * h * 4; i += 2) swap(bb[i], bb[i + 1]); flt_ (u32, i, 0, k * h * 2) cc[i] = bb[i * 2] * bb[i * 2 + 1]; @@ -31,10 +31,10 @@ CEXP auto comp_fps(poly f, poly g) N flt_ (u32, i, 0, k * 2) flt_ (u32, j, 0, n / 2 + 1) aa[(i * h + j) * 2 + n % 2] = a[i * h / 2 + j]; core4.dif(aa); - for (u32 i = 1; i < k * h * 4; i *= 2) std::reverse(bb.begin() + i, bb.begin() + i * 2); + for (u32 i = 1; i < k * h * 4; i *= 2) reverse(bb.begin() + i, bb.begin() + i * 2); flt_ (u32, i, 0, k * h * 4) aa[i] *= bb[i]; core4.dit(aa), a.assign(k * h, 0); - flt_ (u32, i, 0, k) std::copy(aa.begin() + i * h * 2, aa.begin() + i * h * 2 + n + 1, a.begin() + i * h); + flt_ (u32, i, 0, k) copy(aa.begin() + i * h * 2, aa.begin() + i * h * 2 + n + 1, a.begin() + i * h); return a; }; const u32 n = (u32)max(g.size(), f.size()), h = std::bit_ceil(n); diff --git a/src/code/poly/comp_fpssps.hpp b/src/code/poly/comp_fpssps.hpp index 5fcc2a57e..294e0a7be 100644 --- a/src/code/poly/comp_fpssps.hpp +++ b/src/code/poly/comp_fpssps.hpp @@ -27,7 +27,7 @@ auto comp_fpssps(u32 n, poly f, vec g, vec CR fact, vec C auto B = ss.lift(h[k - 1][j + 1]); ss.zeta(B), ss.prod(B, A), ss.mobius(B); auto c = ss.unlift(B); - std::ranges::copy(c, std::back_inserter(h[k][j])); + copy(c, std::back_inserter(h[k][j])); } } return h[n][0]; diff --git a/src/code/poly/compinv_fps.hpp b/src/code/poly/compinv_fps.hpp index 23558dcb3..27fe31e32 100644 --- a/src/code/poly/compinv_fps.hpp +++ b/src/code/poly/compinv_fps.hpp @@ -24,7 +24,7 @@ CEXP auto compinv_fps(poly CR f, vec CR inv, u32 n = 0) } // @return g s.t. $g(f(x)) \equiv x \pmod{\deg(f)+1}$ template