Skip to content

Commit

Permalink
refactor: simplify
Browse files Browse the repository at this point in the history
  • Loading branch information
Tiphereth-A committed Feb 26, 2025
1 parent 8840ed7 commit ec6924d
Show file tree
Hide file tree
Showing 140 changed files with 385 additions and 326 deletions.
3 changes: 3 additions & 0 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ notebook:
- vec_op: vec 运算
code_ext: hpp
test_ext: cpp
- strip: strip
code_ext: hpp
test_ext: cpp
- ndvec: 高维 vector
code_ext: hpp
test_ext: cpp
Expand Down
2 changes: 1 addition & 1 deletion src/code/conv/conv_subset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ struct conv_subset {
}
CEXP vec<arr_t> lift(spn<T> a) CNE {
vec<arr_t> 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<T> unlift(spn<arr_t> A) CNE {
Expand Down
16 changes: 8 additions & 8 deletions src/code/conv/conv_u64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ vecuu conv_u64(vec<T> CR a, vec<T> CR b, u32 ans_size = 0) NE {
fft.bzr(n + m - 1);
u32 s = fft.size();
vec<EI> 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<EI> 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;
Expand Down Expand Up @@ -56,7 +56,7 @@ vecuu conv_u64(vec<T> CR a, vec<T> 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]));
Expand All @@ -66,8 +66,8 @@ vecuu conv_u64(vec<T> CR a, vec<T> CR b, u32 ans_size = 0) NE {
};
mul(mul, pa.data(), pb.data(), pc.data(), s);
vec<T> 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;
}

Expand Down
2 changes: 1 addition & 1 deletion src/code/conv/fft_r2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<u32>(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);
Expand Down
2 changes: 1 addition & 1 deletion src/code/conv/fft_r3.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/code/conv/ntt_doubling.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ CEXP void ntt_doubling(NTT_t CR ntt, vec<mint>& 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
Expand Down
8 changes: 8 additions & 0 deletions src/code/ds/d_ary_heap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <int D, common_range R, class C = std::less<>>
CEXP void make_dary_heap(R CR r, C &&comp = C{}) NE { return make_dary_heap<D>(r.begin(), r.end(), std::forward<C>(comp)); }
template <int D, class I, class C = std::less<>>
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_<D>(i); comp(begin[p], begin[i])) return false;
return true;
}
template <int D, common_range R, class C = std::less<>>
CEXP void is_dary_heap(R CR r, C &&comp = C{}) NE { return is_dary_heap<D>(r.begin(), r.end(), std::forward<C>(comp)); }
template <int D, class I, class C = std::less<>>
CEXP void push_dary_heap(I begin, I end, C &&comp = C{}) NE {
TPN std::iterator_traits<I>::value_type val = std::move(end[-1]);
Expand All @@ -115,6 +119,8 @@ CEXP void push_dary_heap(I begin, I end, C &&comp = C{}) NE {
}
begin[idx] = std::move(val);
}
template <int D, common_range R, class C = std::less<>>
CEXP void push_dary_heap(R CR r, C &&comp = C{}) NE { return push_dary_heap<D>(r.begin(), r.end(), std::forward<C>(comp)); }
template <int D, class I, class C = std::less<>>
CEXP void pop_dary_heap(I begin, I end, C &&comp = C{}) NE {
u32 len = u32(end - begin) - 1;
Expand All @@ -133,6 +139,8 @@ CEXP void pop_dary_heap(I begin, I end, C &&comp = C{}) NE {
}
begin[idx] = std::move(val);
}
template <int D, common_range R, class C = std::less<>>
CEXP void pop_dary_heap(R CR r, C &&comp = C{}) NE { return pop_dary_heap<D>(r.begin(), r.end(), std::forward<C>(comp)); }

} // namespace tifa_libs::ds

Expand Down
10 changes: 10 additions & 0 deletions src/code/ds/depq.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <common_range R, class C = std::less<>>
CEXP bool is_minmax_heap(R CR r, C &&comp = C{}) NE { return is_minmax_heap(r.begin(), r.end(), std::forward<C>(comp)); }
template <class I, class C = std::less<>>
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);
Expand Down Expand Up @@ -147,19 +149,25 @@ void push_minmax_heap(I begin, I end, C &&comp = C{}) NE {
} else break;
begin[idx] = std::move(value);
}
template <common_range R, class C = std::less<>>
CEXP bool push_minmax_heap(R CR r, C &&comp = C{}) NE { return push_minmax_heap(r.begin(), r.end(), std::forward<C>(comp)); }
template <class I, class C = std::less<>>
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 <common_range R, class C = std::less<>>
CEXP bool pop_minmax_heap_min(R CR r, C &&comp = C{}) NE { return pop_minmax_heap_min(r.begin(), r.end(), std::forward<C>(comp)); }
template <class I, class C = std::less<>>
CEXP void pop_minmax_heap_max(I begin, I end, C &&comp = C{}) NE {
u32 l = u32(end - begin) - 1;
if (l <= 1) return;
u32 idx = 1 + !!comp(begin[1], begin[2]);
depq_impl_::pdmax_(begin, std::exchange(end[-1], std::move(begin[idx])), idx, l, std::forward<C>(comp));
}
template <common_range R, class C = std::less<>>
CEXP bool pop_minmax_heap_max(R CR r, C &&comp = C{}) NE { return pop_minmax_heap_max(r.begin(), r.end(), std::forward<C>(comp)); }
template <class I, class C = std::less<>>
CEXP void make_minmax_heap(I begin, I end, C &&comp = C{}) NE {
u32 l = u32(end - begin), idx = l / 2;
Expand Down Expand Up @@ -207,6 +215,8 @@ CEXP void make_minmax_heap(I begin, I end, C &&comp = C{}) NE {
loplim /= 2;
}
}
template <common_range R, class C = std::less<>>
CEXP bool make_minmax_heap(R CR r, C &&comp = C{}) NE { return make_minmax_heap(r.begin(), r.end(), std::forward<C>(comp)); }

} // namespace tifa_libs::ds

Expand Down
2 changes: 1 addition & 1 deletion src/code/ds/lichao_segtree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class lichao_segtree {
CEXPE lichao_segtree(spn<T> 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:
Expand Down
4 changes: 2 additions & 2 deletions src/code/ds/radix_heap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand All @@ -25,7 +25,7 @@ class radix_heap {
}
CEXP std::pair<K, V> 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);
Expand Down
2 changes: 1 addition & 1 deletion src/code/ds/segtree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>(n * 2, E), std::ranges::copy(a, val.begin() + n);
val = vec<T>(n * 2, E), copy(a, val.begin() + n);
if CEXP (enable_tag) tag = vec<F>(n, ID), vset = vecb(n);
for (u32 i = n - 1; i; --i) pushup(i);
}
Expand Down
2 changes: 1 addition & 1 deletion src/code/ds/st_array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class st_array {

CEXP void reset(spn<T> a) NE {
const u32 n = (u32)a.size(), lbn = (u32)std::bit_width(n);
st = vvec<T>(lbn, vec<T>(n)), std::ranges::copy(a, st[0].begin());
st = vvec<T>(lbn, vec<T>(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))))]);
}
Expand Down
2 changes: 1 addition & 1 deletion src/code/edh/base64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Base64 {

public:
static CEXP strn encode(spn<usz> 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)
Expand Down
2 changes: 1 addition & 1 deletion src/code/edh/bwt_inv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
12 changes: 6 additions & 6 deletions src/code/edh/discretization.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
#define TIFALIBS_EDH_DISCRETIZATION

#include "../fast/rsort32.hpp"
#include "../util/traits.hpp"

namespace tifa_libs {

template <iterable_c T>
template <common_range T>
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 <iterable_c T>
template <common_range T>
CEXP std::pair<T, vecu> 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};
}

Expand Down
4 changes: 2 additions & 2 deletions src/code/edh/hash_splitmix64.hpp
Original file line number Diff line number Diff line change
@@ -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 {

Expand Down Expand Up @@ -29,7 +29,7 @@ class hash_splitmix64 {
std::apply([&](Ts CR... targs) NE { ((ret = append(ret, (*this)(targs))), ...); }, tp);
return ret;
}
template <iterable_c T>
template <common_range T>
u64 operator()(T CR tp) CNE {
u64 ret = 0;
for (auto &&i : tp) ret = append(ret, (*this)(i));
Expand Down
9 changes: 5 additions & 4 deletions src/code/fast/rsort32.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace tifa_libs {

template <class C>
requires(std::contiguous_iterator<TPN C::iterator> && std::integral<TPN C::value_type> && sizeof(TPN C::value_type) == 4)
requires(std::is_array_v<C> && std::integral<decltype(std::declval<C>()[0])> && sizeof(std::declval<C>()[0]) == 4) || (std::contiguous_iterator<TPN C::iterator> && std::integral<TPN C::value_type> && 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]{};
Expand All @@ -22,13 +22,14 @@ void rsort32(C& a) NE {
if CEXP (std::is_signed_v<TPN C::value_type>) {
u32 i = n;
while (i && a[i - 1] < 0) --i;
std::rotate(a_, a_ + i, a_ + n);
rotate(a_, a_ + n, a_ + i);
}
}
template <class C>
requires(std::is_array_v<C> && std::integral<decltype(std::declval<C>()[0])> && sizeof(std::declval<C>()[0]) == 4) || range<C>
void sort(C& a) NE {
if CEXP (std::contiguous_iterator<TPN C::iterator> && std::integral<TPN C::value_type> && sizeof(TPN C::value_type) == 4) rsort32(a);
else std::sort(a.begin(), a.end());
if CEXP (std::is_array_v<C> || (std::contiguous_iterator<TPN C::iterator> && std::integral<TPN C::value_type> && sizeof(TPN C::value_type) == 4)) rsort32(a);
else std::ranges::sort(a);
}

} // namespace tifa_libs
Expand Down
3 changes: 2 additions & 1 deletion src/code/game/npuzzle_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/code/geo2d/any_ins_ss.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ CEXP bool any_ins_Ss(vec<line<FP>> 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<FP> CR u, line<FP> 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);
Expand Down
2 changes: 1 addition & 1 deletion src/code/geo2d/argsort.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace tifa_libs::geo {
template <class FP>
CEXP void argsort(vec<point<FP>> &vp, u32 quad_start = 6) NE {
assert(quad_start < 9);
std::ranges::sort(vp, [ofs = 9 - quad_start](point<FP> CR l, point<FP> 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<FP> CR l, point<FP> CR r) NE { return l.quad() == r.quad() ? is_pos(l ^ r) : (l.quad() + ofs) % 9 < (r.quad() + ofs) % 9; });
}

} // namespace tifa_libs::geo
Expand Down
5 changes: 3 additions & 2 deletions src/code/geo2d/aunion_cs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ CEXP vec<FP> aunion_Cs(vec<circle<FP>> 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<arc_t> arcs(n);
Expand Down Expand Up @@ -45,7 +46,7 @@ CEXP vec<FP> aunion_Cs(vec<circle<FP>> 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;
Expand All @@ -66,7 +67,7 @@ CEXP vec<FP> aunion_Cs(vec<circle<FP>> CR cs) NE {
vec<FP> 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]);
Expand Down
4 changes: 2 additions & 2 deletions src/code/geo2d/aunion_pos.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ CEXP vec<FP> aunion_Pos(vec<polygon<FP>> 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;
Expand All @@ -44,7 +44,7 @@ CEXP vec<FP> aunion_Pos(vec<polygon<FP>> CR pos) NE {
}
vec<FP> 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()) {
Expand Down
4 changes: 2 additions & 2 deletions src/code/geo2d/cvh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ struct cvh : public polygon<FP> {
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<FP> CR p) CNE {
auto it = std::lower_bound(this->vs.begin() + 1, this->vs.end(), p, [&](point<FP> CR l, point<FP> 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<FP> CR l, point<FP> 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));
Expand Down
Loading

0 comments on commit ec6924d

Please sign in to comment.