Skip to content

Commit

Permalink
fix: wrong implicit constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
Tiphereth-A committed Mar 18, 2024
1 parent 60640d1 commit 26f427c
Show file tree
Hide file tree
Showing 13 changed files with 73 additions and 64 deletions.
6 changes: 3 additions & 3 deletions src/code/comb/gen_partition.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ namespace tifa_libs::math {
// partition[i] = p(i), i=0,1,...,n
template <class T>
constexpr poly<T> gen_partition(u32 n) {
if (n == 0) return {};
if (n == 0) return poly<T>{1};
poly<T> p(n + 1);
p[0] = 1;
for (u64 k = 1, k1, k2; k <= n; ++k) {
if ((k2 = k * (3 * k - 1) / 2) > n) break;
if ((k1 = k * (3 * k + 1) / 2) <= n) p[k1] += ((k & 1) ? -1 : 1);
if (k2 <= n) p[k2] += ((k & 1) ? -1 : 1);
if ((k1 = k * (3 * k + 1) / 2) <= n) p[(u32)k1] += ((k & 1) ? -1 : 1);
if (k2 <= n) p[(u32)k2] += ((k & 1) ? -1 : 1);
}
return poly_inv(p);
}
Expand Down
3 changes: 1 addition & 2 deletions src/code/conv/conv_u128.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#ifndef TIFALIBS_CONV_CONV_U128
#define TIFALIBS_CONV_CONV_U128

#include "../math/mint.hpp"
#include "../math/mint_s30.hpp"
#include "conv_dft.hpp"
#include "conv_naive.hpp"
Expand All @@ -16,7 +15,7 @@ vec<u128> conv_u128(vec<T> const &l, vec<T> const &r, u32 ans_size = 0) {
using mint0 = mint_s30<m0>;
using mint1 = mint_s30<m1>;
using mint2 = mint_s30<m2>;
static constexpr u32 r01 = mint1(m0).inv().val(), r02 = mint2(m0).inv().val(), r12 = mint2(m1).inv().val(), r02r12 = (u64)r02 * r12 % m2;
static constexpr u32 r01 = inverse(m0, mint1::mod()), r02 = inverse(m0, mint2::mod()), r12 = inverse(m1, mint2::mod()), r02r12 = (u64)r02 * r12 % m2;
static constexpr u64 w1 = m0, w2 = (u64)m0 * m1;

if (!ans_size) ans_size = u32(l.size() + r.size() - 1);
Expand Down
14 changes: 7 additions & 7 deletions src/code/enum/gosper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ class Gosper {
static inline u32 n_, k_;
u64 now_;

static u64 num_begin() { return (1_u64 << k_) - 1; }
static u64 num_end() { return 1_u64 << n_; }
static constexpr u64 num_begin() { return (1_u64 << k_) - 1; }
static constexpr u64 num_end() { return 1_u64 << n_; }

public:
static constexpr void set(u32 n, u32 k) {
assert(k && k <= n && n < 64);
n_ = n;
k_ = k;
}
static Gosper begin() { return num_begin(); }
static Gosper end() { return num_end(); }
static constexpr Gosper begin() { return num_begin(); }
static constexpr Gosper end() { return num_end(); }

constexpr Gosper(u64 now = num_begin()) : now_(now) { assert(now == num_end() || (u32)std::popcount(now) == k_); }
constexpr Gosper(u64 now = num_begin()) : now_(now) { assert(now >= num_end() || (u32)std::popcount(now) == k_); }

constexpr u64 operator*() const { return now_; }
constexpr bool operator!=(Gosper const &x) const { return now_ != x.now_; }
constexpr u64 operator*() const { return std::min(now_, num_end()); }
constexpr bool operator!=(Gosper const &x) const { return std::min(now_, num_end()) != std::min(x.now_, num_end()); }
constexpr void operator++() {
u64 c = bit::lowbit(now_), r = now_ + c;
now_ = ((r ^ now_) / 4 / c) | r;
Expand Down
14 changes: 7 additions & 7 deletions src/code/math/mint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class mint {
public:
constexpr mint() {}
template <int_c T>
constexpr mint(T v) { (D(v)); }
constexpr mint(T v) : v_(D::mod_(v)) {}
constexpr operator D() { return d(); }

using sraw_type = to_sint_t<raw_type>;
Expand All @@ -28,18 +28,18 @@ class mint {
constexpr raw_type &data() { return d().data_(); }

template <int_c T>
explicit constexpr operator T() const { return T(val()); }
explicit constexpr operator T() const { return (T)val(); }
constexpr mint &operator+=(mint const &r) { return d().adde_(r.d()); }
constexpr mint &operator-=(mint const &r) { return d().sube_(r.d()); }
constexpr mint &operator*=(mint const &r) { return d().mule_(r.d()); }
constexpr mint &operator/=(mint const &r) { return *this = *this * r.inv(); }
constexpr mint const &operator+() const { return d(); }
constexpr mint const &operator+() const { return *this; }
constexpr mint operator-() const { return d().neg_(); }
constexpr mint inv() const { return inverse(val(), mod()); }
friend constexpr mint operator+(mint l, mint const &r) { return l += r.d(); }
friend constexpr mint operator-(mint l, mint const &r) { return l -= r.d(); }
friend constexpr mint operator*(mint l, mint const &r) { return l *= r.d(); }
friend constexpr mint operator/(mint l, mint const &r) { return l /= r.d(); }
friend constexpr mint operator+(mint l, mint const &r) { return l += r; }
friend constexpr mint operator-(mint l, mint const &r) { return l -= r; }
friend constexpr mint operator*(mint l, mint const &r) { return l *= r; }
friend constexpr mint operator/(mint l, mint const &r) { return l /= r; }
friend constexpr bool operator==(mint const &l, mint const &r) { return l.val() == r.val(); }
friend constexpr auto operator<=>(mint const &l, mint const &r) { return l.sval() - r.sval(); }
friend std::istream &operator>>(std::istream &is, mint &x) {
Expand Down
15 changes: 7 additions & 8 deletions src/code/math/mint_2e61n1.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,6 @@ class mint_2e61n1 : public mint<mint_2e61n1, u64> {
static constexpr u64 MOD = (1ull << 61) - 1;
static constexpr u64 _30 = (1 << 30) - 1, _31 = (1u << 31) - 1;

// clang-format off
template <uint_c T>
static constexpr u64 mod_(T x) { return x < MOD ? (u64)x : (x = (x & MOD) + ((u64)x >> 61)) > MOD ? x - MOD : (u64)x; }
template <sint_c T>
static constexpr u64 mod_(T x) { return x >= 0 ? mod_(to_uint_t<T>(x)) : MOD - mod_(to_uint_t<T>(-x)); }
// clang-format on

public:
constexpr mint_2e61n1() {}
template <int_c T>
Expand All @@ -26,11 +19,17 @@ class mint_2e61n1 : public mint<mint_2e61n1, u64> {
private:
using raw_t = u64;
using sraw_t = i64;
// clang-format off
template <uint_c T>
static constexpr raw_t mod_(T x) { return x < MOD ? (raw_t)x : (x = (x & MOD) + ((raw_t)x >> 61)) > MOD ? x - MOD : (raw_t)x; }
template <sint_c T>
static constexpr raw_t mod_(T x) { return x >= 0 ? mod_(to_uint_t<T>(x)) : MOD - mod_(to_uint_t<T>(-x)); }
// clang-format on
static constexpr raw_t mod_() { return MOD; }
constexpr raw_t val_() const { return this->v_; }
constexpr raw_t &data_() { return this->v_; }

constexpr mint_2e61n1 neg_() const { return MOD - val_(); }
constexpr mint_2e61n1 neg_() const { return mint_2e61n1(MOD - val_()); }
constexpr mint_2e61n1 &adde_(mint_2e61n1 const &r) {
data_() = mod_(val_() + r.val_());
return *this;
Expand Down
12 changes: 7 additions & 5 deletions src/code/math/mint_d31.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ class mint_d31 : public mint<mint_d31<ID>, u32> {

static inline u32 R, R2, MOD, MOD_ODD, OFFSET, MASK;

static constexpr u32 norm(i32 x) { return (u32)(x + (-(x < 0) & (i32)MOD)); }
static constexpr u32 norm(i32 x) { return u32(x + (-(x < 0) & (i32)MOD)); }
static constexpr u32 redc(u64 x) {
u32 t = (u32)((x + (u64)((u32)(x)*R) * MOD_ODD) >> 32);
u32 t = u32((x + u64((u32)x * R) * MOD_ODD) >> 32);
return t - (MOD_ODD & -((MOD_ODD - 1 - t) >> 31));
}
static constexpr u32 tsf(u32 x) { return redc((u64)(x % MOD_ODD) * R2) << OFFSET | (x & MASK); }
static constexpr u32 tsf(u32 x) { return redc(u64(x % MOD_ODD) * R2) << OFFSET | (x & MASK); }

public:
static constexpr void set_mod(u32 m) {
Expand All @@ -32,17 +32,19 @@ class mint_d31 : public mint<mint_d31<ID>, u32> {

constexpr mint_d31() {}
template <int_c T>
constexpr mint_d31(T v) { this->v_ = tsf(norm(i32(v % (std::conditional_t<sint_c<T>, i32, u32>)mod_()))); }
constexpr mint_d31(T v) { this->v_ = mod_(v); }

private:
using raw_t = u32;
using sraw_t = i32;
template <int_c T>
static constexpr raw_t mod_(T v) { return tsf(norm(i32(v % (std::conditional_t<sint_c<T>, i32, u32>)mod_()))); }
static constexpr raw_t mod_() { return MOD; }
constexpr raw_t val_() const {
raw_t h = redc(this->v_ >> OFFSET);
return ((h - this->v_) * R & MASK) * MOD_ODD + h;
}
constexpr raw_t &data_() { return this->v_; }
constexpr raw_t &data_() { return this->v_; }

constexpr mint_d31 neg_() const {
mint_d31 res;
Expand Down
8 changes: 5 additions & 3 deletions src/code/math/mint_d63.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ class mint_d63 : public mint<mint_d63<ID>, u64> {
static inline u64 MOD, R, R2;

static constexpr u64 mul_h(u64 x, u64 y) {
u64 a = x >> 32, b = (u32)(x), c = y >> 32, d = (u32)(y), ad = a * d, bc = b * c;
u64 a = x >> 32, b = (u32)x, c = y >> 32, d = (u32)y, ad = a * d, bc = b * c;
return a * c + (ad >> 32) + (bc >> 32) + (((ad & 0xFFFFFFFF) + (bc & 0xFFFFFFFF) + (b * d >> 32)) >> 32);
}
static constexpr u64 redc_mul(u64 x, u64 y) {
u64 res = mul_h(x, y) - mul_h(x * y * R, MOD);
return res + (MOD & -(res >> 63));
}
static constexpr u64 norm(i64 x) { return (u64)(x + (i64)(MOD & (u64)(-(x < 0)))); }
static constexpr u64 norm(i64 x) { return u64(x + i64(MOD & u64(-(x < 0)))); }

public:
static constexpr void set_mod(u64 m) {
Expand All @@ -35,11 +35,13 @@ class mint_d63 : public mint<mint_d63<ID>, u64> {

constexpr mint_d63() {}
template <int_c T>
constexpr mint_d63(T v) { this->v_ = redc_mul(norm(i64(v % (std::conditional_t<sint_c<T>, i64, u64>)mod_())), R2); }
constexpr mint_d63(T v) { this->v_ = mod_(v); }

private:
using raw_t = u64;
using sraw_t = i64;
template <int_c T>
static constexpr raw_t mod_(T v) { return redc_mul(norm(i64(v % (std::conditional_t<sint_c<T>, i64, u64>)mod_())), R2); }
static constexpr raw_t mod_() { return MOD; }
constexpr raw_t val_() const {
raw_t res = -mul_h(this->v_ * R, MOD);
Expand Down
18 changes: 10 additions & 8 deletions src/code/math/mint_ds.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,20 @@ class mint_ds : public mint<mint_ds<ID>, u32> {
bt_ = barrett(m);
}

constexpr mint_ds() { this->v_ = 0; }
template <sint_c T>
constexpr mint_ds(T v) : mint_ds() {
i64 x = i64(v % (i64)mod_());
this->v_ = raw_t(x + (x < 0 ? mod_() : 0));
}
template <uint_c T>
constexpr mint_ds(T v) { this->v_ = raw_t(v % mod_()); }
constexpr mint_ds() {}
template <int_c T>
constexpr mint_ds(T v) { this->v_ = mod_(v); }

private:
using raw_t = u32;
using sraw_t = i32;
template <sint_c T>
static constexpr raw_t mod_(T v) {
i64 x = i64(v % (i64)mod_());
return raw_t(x + (x < 0 ? mod_() : 0));
}
template <uint_c T>
static constexpr raw_t mod_(T v) { return raw_t(v % mod_()); }
static constexpr raw_t mod_() { return bt_.umod(); }
constexpr raw_t val_() const { return this->v_; }
constexpr raw_t &data_() { return this->v_; }
Expand Down
12 changes: 7 additions & 5 deletions src/code/math/mint_s30.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,21 @@ class mint_s30 : public mint<mint_s30<MOD>, u32> {
static_assert((MOD >> 30) == 0);
static_assert(MOD != 1);

static constexpr u32 reduce(u64 x) { return (u32)((x + (u64)((u32)(x)*R) * MOD) >> 32); }
static constexpr u32 reduce(u64 x) { return u32((x + u64((u32)x * R) * MOD) >> 32); }
static constexpr u32 norm(u32 x) { return x - (MOD & -((MOD - 1 - x) >> 31)); }

public:
constexpr mint_s30() {}
template <sint_c T>
constexpr mint_s30(T v) { this->v_ = reduce(u64(v % (i32)mod_() + (i32)mod_()) * R2); }
template <uint_c T>
constexpr mint_s30(T v) { this->v_ = reduce(u64(v % mod_()) * R2); }
template <int_c T>
constexpr mint_s30(T v) { this->v_ = mod_(v); }

private:
using raw_t = u32;
using sraw_t = i32;
template <sint_c T>
static constexpr raw_t mod_(T v) { return reduce(u64(v % (i32)mod_() + (i32)mod_()) * R2); }
template <uint_c T>
static constexpr raw_t mod_(T v) { return reduce(u64(v % mod_()) * R2); }
static constexpr raw_t mod_() { return MOD; }
constexpr raw_t val_() const { return norm(reduce(this->v_)); }
constexpr raw_t &data_() { return this->v_; }
Expand Down
10 changes: 6 additions & 4 deletions src/code/math/mint_s63.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,29 @@ class mint_s63 : public mint<mint_s63<MOD>, u64> {
static_assert((MOD >> 63) == 0);
static_assert(MOD != 1);

static constexpr u64 mul_h(u64 x, u64 y) {
static constexpr u64 mulh(u64 x, u64 y) {
u64 a = x >> 32, b = (u32)(x), c = y >> 32, d = (u32)(y), ad = a * d, bc = b * c;
return a * c + (ad >> 32) + (bc >> 32) + (((ad & 0xFFFFFFFF) + (bc & 0xFFFFFFFF) + (b * d >> 32)) >> 32);
}
static constexpr u64 redc_mul(u64 x, u64 y) {
u64 res = mul_h(x, y) - mul_h(x * y * R, MOD);
u64 res = mulh(x, y) - mulh(x * y * R, MOD);
return res + (MOD & -(res >> 63));
}
static constexpr u64 norm(i64 x) { return (u64)x + (MOD & -(x < 0)); }

public:
constexpr mint_s63() {}
template <int_c T>
constexpr mint_s63(T v) { this->v_ = redc_mul(norm(v % (std::conditional_t<sint_c<T>, i64, u64>)mod_()), R2); }
constexpr mint_s63(T v) { this->v_ = mod_(v); }

private:
using raw_t = u64;
using sraw_t = i64;
template <int_c T>
static constexpr raw_t mod_(T v) { return redc_mul(norm(v % (std::conditional_t<sint_c<T>, i64, u64>)mod_()), R2); }
static constexpr raw_t mod_() { return MOD; }
constexpr raw_t val_() const {
raw_t res = -mul_h(this->v_ * R, mod_());
raw_t res = -mulh(this->v_ * R, mod_());
return res + (MOD & -(res >> 63));
}
constexpr raw_t &data_() { return this->v_; }
Expand Down
18 changes: 10 additions & 8 deletions src/code/math/mint_ss.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,20 @@ class mint_ss : public mint<mint_ss<MOD>, u32> {
static_assert(MOD >= 1);

public:
constexpr mint_ss() { this->v_ = 0; }
template <sint_c T>
constexpr mint_ss(T v) : mint_ss() {
i64 x = i64(v % (i64)mod_());
this->v_ = raw_t(x + (x < 0 ? mod_() : 0));
}
template <uint_c T>
constexpr mint_ss(T v) { this->v_ = raw_t(v % mod_()); }
constexpr mint_ss() {}
template <int_c T>
constexpr mint_ss(T v) { this->v_ = mod_(v); }

private:
using raw_t = u32;
using sraw_t = i32;
template <sint_c T>
static constexpr raw_t mod_(T v) {
i64 x = i64(v % (i64)mod_());
return raw_t(x + (x < 0 ? mod_() : 0));
}
template <uint_c T>
static constexpr raw_t mod_(T v) { return raw_t(v % mod_()); }
static constexpr raw_t mod_() { return MOD; }
constexpr raw_t val_() const { return this->v_; }
constexpr raw_t &data_() { return this->v_; }
Expand Down
4 changes: 2 additions & 2 deletions src/test_cpverifier/unit-test/enum/gosper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ using mint = tifa_libs::math::mint_s30<998244353>;
template <u32 ID>
void test(u32 n, u32 kmax) {
using Gosper = tifa_libs::Gosper<ID>;
auto binom = tifa_libs::math::Binom<mint>(n);
for (u32 k = 0; k <= kmax; ++k) {
tifa_libs::math::Binom<mint> binom(n);
for (u32 k = 1; k <= kmax; ++k) {
Gosper::set(n, k);
Gosper gs;
u32 cnt = 0, cnt_correct = binom.mCn(n, k).val();
Expand Down
3 changes: 1 addition & 2 deletions src/test_cpverifier/unit-test/nt/lsieve2.bzoj4407.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

using mint = tifa_libs::math::mint_s30<1'000'000'000 + 7>;


void test(strn const& data) {
strn path = "src/data/bzoj/4407/" + data;
std::ifstream fin(path + ".in"), fans(path + ".out");
Expand All @@ -25,7 +24,7 @@ void test(strn const& data) {
tifa_libs::math::lsieve2 ls(n);
static mint pk, lst;
vec<mint> g = ls.template run<mint>(
[&](u32 p, u32 e) {
[&](u32 p, u32 e) -> mint {
if (e == 1) return lst = (pk = tifa_libs::math::qpow<mint>(p, k)) - 1;
else return lst *= pk;
});
Expand Down

0 comments on commit 26f427c

Please sign in to comment.