From 0bad4b84c093f3dc0ebcf297206fe83203ef85ee Mon Sep 17 00:00:00 2001 From: samzhang Date: Mon, 22 Jun 2020 04:14:50 +1200 Subject: [PATCH 01/51] fix --- "\345\207\240\344\275\225/Geometry.cpp" | 142 +++++++++--------- .../Centroid-Decomposition.cpp" | 2 +- .../Heavy-Light-Decomposition.cpp" | 5 + ...70\350\247\201\351\224\231\350\257\257.md" | 16 -- 4 files changed, 80 insertions(+), 85 deletions(-) diff --git "a/\345\207\240\344\275\225/Geometry.cpp" "b/\345\207\240\344\275\225/Geometry.cpp" index 2d63ae1..455aba0 100644 --- "a/\345\207\240\344\275\225/Geometry.cpp" +++ "b/\345\207\240\344\275\225/Geometry.cpp" @@ -1,159 +1,165 @@ using flt = double; using int64 = long long; -const flt eps = 1e-8, pi = acos(-1.0); +const flt eps = 1e-8, pi = acos (-1.0); template -inline int sgn(T x, T e = eps) { return x < -e ? -1 : x > e; } +inline int sgn (T x, T e = eps) { return x < -e ? -1 : x > e; } template -inline T cmp(T a, T b, T e = eps) { - return std::abs(a - b) >= e + std::abs(a) * e ? a - b : 0; +inline T cmp (T a, T b, T e = eps) { + return std::abs (a - b) >= e + std::abs (a) * e ? a - b : 0; } -inline flt fix(flt x, flt e = eps) { return cmp(x, flt(0), e); } +inline flt fix (flt x, flt e = eps) { return cmp (x, flt (0), e); } template struct Point { T x, y; - Point(T x = 0, T y = 0) : x(x), y(y) {} + Point (T x = 0, T y = 0) : x (x), y (y) {} - bool operator<(const Point &o) const { return x < o.x || (x == o.x && y < o.y); } + bool operator< (const Point &o) const { return x < o.x || (x == o.x && y < o.y); } - bool operator==(const Point &o) const { return x == o.x && y == o.y; } + bool operator== (const Point &o) const { return x == o.x && y == o.y; } - Point operator+(const Point &o) const { return Point(x + o.x, y + o.y); } + Point operator+ (const Point &o) const { return Point (x + o.x, y + o.y); } - Point operator-(const Point &o) const { return Point(x - o.x, y - o.y); } + Point operator- (const Point &o) const { return Point (x - o.x, y - o.y); } - Point operator*(T k) const { return Point(x * k, y * k); } + Point operator* (T k) const { return Point (x * k, y * k); } - Point operator/(T k) const { return Point(x / k, y / k); } + Point operator/ (T k) const { return Point (x / k, y / k); } - T dot(const Point &o) const { return x * o.x + y * o.y; } + T dot (const Point &o) const { return x * o.x + y * o.y; } - T det(const Point &o) const { return x * o.y - y * o.x; } + T det (const Point &o) const { return x * o.y - y * o.x; } - T norm2() const { return x * x + y * y; } + T norm2 () const { return x * x + y * y; } - flt norm() const { return hypot(x, y); } + flt norm () const { return hypot (x, y); } - flt ang() const { return atan2(y, x); } + flt ang () const { return atan2 (y, x); } - Point perp() const { return Point(-y, x); } // rotate 90 degrees - Point unit() const { return *this / norm(); } + Point perp () const { return Point (-y, x); } // rotate 90 degrees + Point unit () const { return *this / norm (); } - Point trunc(flt k) const { return unit() * k; } + Point trunc (flt k) const { return unit () * k; } // counter clockwise rotate a rad - Point rot(flt a) const { - return Point(x * cos(a) - y * sin(a), x * sin(a) + y * cos(a)); + Point rot (flt a) const { + return Point (x * cos (a) - y * sin (a), x * sin (a) + y * cos (a)); } // counter clockwise rotate using cos/sin - Point rot(flt cosa, flt sina) const { - return Point(x * cosa - y * sina, x * sina + y * cosa); + Point rot (flt cosa, flt sina) const { + return Point (x * cosa - y * sina, x * sina + y * cosa); } + + friend ostream &operator<< (ostream &out, const Point &p) { + out<<"("<; using poly_t = std::vector; template -bool on_seg(const P &a, const P &b, const P &o) { - return sgn((a - o).det(b - o)) == 0 && sgn((a - o).dot(b - o)) <= 0; +bool on_seg (const P &a, const P &b, const P &o) { + return sgn ((a - o).det (b - o)) == 0 && sgn ((a - o).dot (b - o)) <= 0; } template -bool is_parallel(const P &a, const P &b, const P &c, const P &d) { - return sgn((b - a).det(d - c)) == 0; +bool is_parallel (const P &a, const P &b, const P &c, const P &d) { + return sgn ((b - a).det (d - c)) == 0; } // find intersection of segments ab and cd, stored in p template -bool seg_inter(const P &a, const P &b, const P &c, const P &d, P &p) { - if(on_seg(a, b, c)) return p = c, true; - if(on_seg(a, b, d)) return p = d, true; - if(on_seg(c, d, a)) return p = a, true; - if(on_seg(c, d, b)) return p = b, true; +bool seg_inter (const P &a, const P &b, const P &c, const P &d, P &p) { + if (on_seg (a, b, c)) return p = c, true; + if (on_seg (a, b, d)) return p = d, true; + if (on_seg (c, d, a)) return p = a, true; + if (on_seg (c, d, b)) return p = b, true; P ab{b - a}, cd{d - c}; - if(sgn(ab.det(cd)) == 0) return false; // parallel - int d1 = sgn(ab.det(c - a)) * sgn(ab.det(d - a)); - int d2 = sgn(cd.det(a - c)) * sgn(cd.det(b - c)); - p = a + ab * (cd.det(c - a) / cd.det(ab)); + if (sgn (ab.det (cd)) == 0) return false; // parallel + int d1 = sgn (ab.det (c - a)) * sgn (ab.det (d - a)); + int d2 = sgn (cd.det (a - c)) * sgn (cd.det (b - c)); + p = a + ab * (cd.det (c - a) / cd.det (ab)); return d1 < 0 && d2 < 0; } // find intersection of lines ab and cd, stored in p template -bool line_inter(const P &a, const P &b, const P &c, const P &d, P &p) { +bool line_inter (const P &a, const P &b, const P &c, const P &d, P &p) { P ab{b - a}, cd{d - c}; - if(sgn(ab.det(cd)) == 0) return false; // parallel - p = a + ab * (cd.det(c - a) / cd.det(ab)); + if (sgn (ab.det (cd)) == 0) return false; // parallel + p = a + ab * (cd.det (c - a) / cd.det (ab)); return true; } // minimum distance from o to segment ab template -flt dis2seg(const P &a, const P &b, const P &o) { +flt dis2seg (const P &a, const P &b, const P &o) { P ao{o - a}, bo{o - b}, ab{b - a}; - if(sgn(ao.dot(ab)) < 0) return ao.norm(); - if(sgn(-bo.dot(ab)) < 0) return bo.norm(); - return std::abs(ao.det(ab)) / ab.norm(); + if (sgn (ao.dot (ab)) < 0) return ao.norm (); + if (sgn (-bo.dot (ab)) < 0) return bo.norm (); + return std::abs (ao.det (ab)) / ab.norm (); } // find the minimum distance from segment ab to segment cd template -flt dis_seg2seg(const P &a, const P &b, const P &c, const P &d) { +flt dis_seg2seg (const P &a, const P &b, const P &c, const P &d) { P o; - if(seg_inter(a, b, c, d, o)) return 0; + if (seg_inter (a, b, c, d, o)) return 0; else - return std::min(std::min(dis2seg(a, b, c), dis2seg(a, b, d)), - std::min(dis2seg(c, d, a), dis2seg(c, d, b))); + return std::min (std::min (dis2seg (a, b, c), dis2seg (a, b, d)), + std::min (dis2seg (c, d, a), dis2seg (c, d, b))); } // move line AB along normal vector -void move_d(point &a, point &b, const flt len) { - auto d = (b - a).perp().trunc(len); +void move_d (point &a, point &b, const flt len) { + auto d = (b - a).perp ().trunc (len); a = a + d, b = b + d; } // project point o on line ab -point project(const point &a, const point &b, const point &o) { +point project (const point &a, const point &b, const point &o) { auto ab = b - a; - return a + ab * (ab.dot(o - a) / ab.norm2()); + return a + ab * (ab.dot (o - a) / ab.norm2 ()); } // find the reflect point of o with respect to line ab -point reflect(const point &a, const point &b, const point &o) { +point reflect (const point &a, const point &b, const point &o) { auto ab = b - a; - return (a + ab * (ab.dot(o - a) / ab.norm2())) * 2 - o; + return (a + ab * (ab.dot (o - a) / ab.norm2 ())) * 2 - o; } /************************************ Circle Utilities *****************************************/ // check if two circles intersect, intersection will store in P and Q -bool intersect(const point &A, flt ra, const point &B, flt rb, point &P, point &Q) { - point AB(B - A); - double dis = AB.norm(); - if (sgn(dis) == 0 || sgn (dis - (ra + rb)) > 0 || sgn (dis - fabs (ra - rb)) < 0) return false; +bool intersect (const point &A, flt ra, const point &B, flt rb, point &P, point &Q) { + point AB (B - A); + double dis = AB.norm (); + if (sgn (dis) == 0 || sgn (dis - (ra + rb)) > 0 || sgn (dis - fabs (ra - rb)) < 0) return false; flt cosa = (dis * dis + ra * ra - rb * rb) / (2 * dis * ra); - flt sina = sqrt(fix(1.0 - cosa * cosa)); + flt sina = sqrt (fix (1.0 - cosa * cosa)); AB = AB * (ra / dis); - P = AB.rot(cosa, +sina) + A; - Q = AB.rot(cosa, -sina) + A; + P = AB.rot (cosa, +sina) + A; + Q = AB.rot (cosa, -sina) + A; return true; } // check if line AB intesect circle O, intersection will store in P and Q -bool intersect(const point &A, const point &B, const point &O, flt r, point &P, point &Q) { - point AB(B - A), AO(O - A); - flt dis = fabs(AB.det(AO)) / AB.norm(); - if(sgn(dis - r) > 0) return false; - point M = A + AB * (AB.dot(AO) / AB.norm2()); - dis = sqrt(fix(r * r - dis * dis)); - AB = AB / AB.norm() * dis; +bool intersect (const point &A, const point &B, const point &O, flt r, point &P, point &Q) { + point AB (B - A), AO (O - A); + flt dis = fabs (AB.det (AO)) / AB.norm (); + if (sgn (dis - r) > 0) return false; + point M = A + AB * (AB.dot (AO) / AB.norm2 ()); + dis = sqrt (fix (r * r - dis * dis)); + AB = AB / AB.norm () * dis; P = M + AB, Q = M - AB; return true; } diff --git "a/\345\233\276\350\256\272/Centroid-Decomposition.cpp" "b/\345\233\276\350\256\272/Centroid-Decomposition.cpp" index f5390d9..69c28ed 100644 --- "a/\345\233\276\350\256\272/Centroid-Decomposition.cpp" +++ "b/\345\233\276\350\256\272/Centroid-Decomposition.cpp" @@ -31,7 +31,7 @@ namespace CentroidDecomposition { int solve(int root) { calc_size(root, -1); - PII center = MP(inf, -1); + PII center = MP(1e9, -1); find_center(root, -1, siz[root], center); vis[center.se] = true; for(auto e:adj[center.se]) { diff --git "a/\345\233\276\350\256\272/Heavy-Light-Decomposition.cpp" "b/\345\233\276\350\256\272/Heavy-Light-Decomposition.cpp" index 2b8a16a..a1657d5 100644 --- "a/\345\233\276\350\256\272/Heavy-Light-Decomposition.cpp" +++ "b/\345\233\276\350\256\272/Heavy-Light-Decomposition.cpp" @@ -12,6 +12,11 @@ namespace HLD { int dfnToID[maxn], dfn[maxn], head[maxn], fa[maxn], size[maxn], heavy[maxn], r[maxn], cnt = 1; ll dep[maxn]; + void addEdge (int u, int v, int len = 1) { + adj[u].emplace_back (v, len); + adj[v].emplace_back (u, len); + } + void firstDfs(int cur, int _fa) { size[cur] = 1; fa[cur] = _fa; diff --git "a/\345\270\270\350\247\201\351\224\231\350\257\257.md" "b/\345\270\270\350\247\201\351\224\231\350\257\257.md" index ae8b6e2..bdaa862 100644 --- "a/\345\270\270\350\247\201\351\224\231\350\257\257.md" +++ "b/\345\270\270\350\247\201\351\224\231\350\257\257.md" @@ -21,21 +21,5 @@ - 取消同步后混用 - 二分时有负数要写 `l+(r-l)/2` -```bash -alias gao=g++ -O2 -Wall -Wextra -pedantic -Wshadow -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -fsanitize=address -fsanitize=undefined -``` -``` bash -while true; do - ./generate > input - ./run < input > output - ./std < input > answer - if diff output answer; then - echo OK - else - echo WA - break - fi -done -``` From 886f12d205fb98d2ca987977ebcdb2df6b818874 Mon Sep 17 00:00:00 2001 From: samzhang Date: Mon, 22 Jun 2020 17:56:11 +1200 Subject: [PATCH 02/51] Update Fast-Fourier-Transform.cpp --- .../Fast-Fourier-Transform.cpp" | 47 +++++-------------- 1 file changed, 13 insertions(+), 34 deletions(-) diff --git "a/\346\225\260\345\255\246/Fast-Fourier-Transform.cpp" "b/\346\225\260\345\255\246/Fast-Fourier-Transform.cpp" index 09a5561..d40257a 100644 --- "a/\346\225\260\345\255\246/Fast-Fourier-Transform.cpp" +++ "b/\346\225\260\345\255\246/Fast-Fourier-Transform.cpp" @@ -2,11 +2,11 @@ namespace fft { const int N = 1<<20, M = 31768; struct Complex { - double x, y; + long double x, y; Complex () { x = y = 0; } - Complex (double _x, double _y) { x = _x, y = _y; } + Complex (long double _x, long double _y) { x = _x, y = _y; } Complex operator+ (const Complex &r) const { return Complex (x + r.x, y + r.y); @@ -16,11 +16,11 @@ namespace fft { return Complex (x - r.x, y - r.y); } - Complex operator* (const double k) const { + Complex operator* (const long double k) const { return Complex (x * k, y * k); } - Complex operator/ (const double k) const { + Complex operator/ (const long double k) const { return Complex (x / k, y / k); } @@ -38,14 +38,14 @@ namespace fft { } }; - const double pi = acos (-1.0); + const long double pi = M_PI; Complex w[N]; int rev[N]; void init (int L) { int n = 1<>1]>>1) | ((i & 1)<<(L - 1)); } @@ -77,31 +77,8 @@ namespace fft { Complex A[N], B[N], C1[N], C2[N]; - std::vector conv (const std::vector &a, const std::vector &b) { - int n = a.size (), m = b.size (), L = 0, s = 1; - while (s <= n + m - 2) s <<= 1, ++L; - init (L); - for (int i = 0; i < s; ++i) { - A[i] = i < n ? Complex (a[i], 0) : Complex (); - B[i] = i < m ? Complex (b[i], 0) : Complex (); - } - trans (A, s, 1); - trans (B, s, 1); - for (int i = 0; i < s; ++i) { - A[i] = A[i] * B[i]; - } - for (int i = 0; i < s; ++i) { - w[i] = w[i].conj (); - } - trans (A, s, -1); - std::vector res (n + m - 1); - for (int i = 0; i < n + m - 1; ++i) { - res[i] = (ll) (A[i].x + 0.5); - } - return res; - } - std::vector fast_conv (const std::vector &a, const std::vector &b) { + VLL conv (const VI &a, const VI &b) { int n = a.size (), m = b.size (), L = 0, s = 1; for (; s <= n + m - 2; s <<= 1, ++L); s >>= 1, --L; @@ -119,9 +96,9 @@ namespace fft { C1[i] = (Complex (4, 0) * (A[j] * B[j]).conj () - (A[j].conj () - A[i]) * (B[j].conj () - B[i]) * (w[i] + Complex (1, 0))) * Complex (0, 0.25); } - std::reverse (w + 1, w + s); + reverse (w + 1, w + s); trans (C1, s, -1); - std::vector res (n + m); + VLL res (n + m); for (int i = 0; i <= (n + m - 1) / 2; ++i) { res[i<<1] = ll (C1[i].y + 0.5); res[i<<1 | 1] = ll (C1[i].x + 0.5); @@ -130,9 +107,9 @@ namespace fft { return res; } - // arbitrary modulo convolution - void conv (int a[], int b[], int n, int m, int mod, int res[]) { + VI conv (const VI &a, const VI &b, const int mod) { int s = 1, L = 0; + const int n = a.size (), m = b.size (); while (s <= n + m - 2) s <<= 1, ++L; init (L); for (int i = 0; i < s; ++i) { @@ -154,6 +131,7 @@ namespace fft { } trans (C1, s, -1); trans (C2, s, -1); + VI res (n + m - 1); for (int i = 0; i < n + m - 1; ++i) { int x = ll (C1[i].x + 0.5) % mod; int y1 = ll (C1[i].y + 0.5) % mod; @@ -161,5 +139,6 @@ namespace fft { int z = ll (C2[i].y + 0.5) % mod; res[i] = ((ll) x * M * M + (ll) (y1 + y2) * M + z) % mod; } + return res; } } From 1b304002bb588b23a3240a28ade1a90629e50f29 Mon Sep 17 00:00:00 2001 From: samzhang Date: Mon, 22 Jun 2020 23:36:32 +1200 Subject: [PATCH 03/51] Update Fast-Fourier-Transform.cpp --- "\346\225\260\345\255\246/Fast-Fourier-Transform.cpp" | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git "a/\346\225\260\345\255\246/Fast-Fourier-Transform.cpp" "b/\346\225\260\345\255\246/Fast-Fourier-Transform.cpp" index d40257a..48b7c15 100644 --- "a/\346\225\260\345\255\246/Fast-Fourier-Transform.cpp" +++ "b/\346\225\260\345\255\246/Fast-Fourier-Transform.cpp" @@ -107,14 +107,13 @@ namespace fft { return res; } - VI conv (const VI &a, const VI &b, const int mod) { + VI conv (const VI &a, const VI &b, const int n, const int m, const int mod) { int s = 1, L = 0; - const int n = a.size (), m = b.size (); while (s <= n + m - 2) s <<= 1, ++L; init (L); for (int i = 0; i < s; ++i) { - A[i] = i < n ? Complex (a[i] / M, a[i] % M) : Complex (); - B[i] = i < m ? Complex (b[i] / M, b[i] % M) : Complex (); + A[i] = i < n ? Complex (MOD (a[i], mod) / M, MOD (a[i], mod) % M) : Complex (); + B[i] = i < m ? Complex (MOD (b[i], mod) / M, MOD (b[i], mod) % M) : Complex (); } trans (A, s, 1); trans (B, s, 1); From b310c2c191949a8a1e1d33d9b63b77421db7436a Mon Sep 17 00:00:00 2001 From: samzhang Date: Tue, 23 Jun 2020 05:15:07 +1200 Subject: [PATCH 04/51] Update Polynomial.cpp --- "\346\225\260\345\255\246/Polynomial.cpp" | 202 ++++++++++++++-------- 1 file changed, 128 insertions(+), 74 deletions(-) diff --git "a/\346\225\260\345\255\246/Polynomial.cpp" "b/\346\225\260\345\255\246/Polynomial.cpp" index 7552138..45d7f30 100644 --- "a/\346\225\260\345\255\246/Polynomial.cpp" +++ "b/\346\225\260\345\255\246/Polynomial.cpp" @@ -1,96 +1,150 @@ -using fft::N; - - -// call init before use -namespace Poly { - int tmp1[N], tmp2[N], tmp3[N], mod = 998244353; - int iv[N]; +namespace NTT { + const int mod = 998244353, g = 3; - void init () { - iv[1] = 1; - for (int i = 2; i < N; ++i) { - iv[i] = (mod - (ll) mod / i * iv[mod % i] % mod); + void bit_reverse_swap (VI &a) { + int n = sz(a); + for (int i = 1, j = n>>1, k; i < n - 1; i++) { + if (i < j) swap (a[i], a[j]); + for (k = n>>1; j >= k; j -= k, k >>= 1); + j += k; } } - void prepare (int poly[], int n) { - for (int i = 0; i < n; i++)poly[i] = MOD (poly[i], mod); + void NTT (VI &a, int type) { + bit_reverse_swap (a); + int n = sz (a); + for (int i = 2; i <= n; i *= 2) { + const auto wi = fast (g, type * (mod - 1) / i, mod); // fp(g, (mod - 1) / i) 是 i 次单位根 + for (int j = 0; j < n; j += i) { + ll w = 1; + for (int k = j, h = i / 2; k < j + h; k++) { + int t = w * a[k + h] % mod, u = a[k]; + a[k] = (u + t) % mod; + a[k + h] = (u - t + mod) % mod; + w = w * wi % mod; + } + } + } + const ll inv = inverse (n, mod); + if (type == -1) for (auto &x : a) x = x * inv % mod; } - // res = 1 / poly - void inv (int poly[], int res[], int n) { - prepare (poly, n); - int deg = n - 1; - std::vector degs; - while (deg > 0) { - degs.push_back (deg); - deg >>= 1; + + VI conv (const VI &a, const VI &b, const int n, const int m, const int mod = NTT::mod) { + VI _a (begin (a), begin (a) + n); + VI _b (begin (b), begin (b) + m); + int len = 1; + while (len <= n + m - 2) len <<= 1; + while (len != lowbit(len)) len += lowbit(len); + _a.resize (len), _b.resize (len); + NTT (_a, 1), NTT (_b, 1); + REP(i, 0, len) _a[i] = (ll) _a[i] * _b[i] % mod; + NTT (_a, -1); + _a.resize (n + m - 1); + return _a; + } +} + + +namespace Poly { + using NTT::mod; + using NTT::conv; + VI iv ({0, 1}); + + void init (const int n) { + while (sz(iv) < n) { + iv.emplace_back ((mod - (ll) mod / sz(iv) * iv[mod % sz(iv)] % mod)); } - std::reverse (degs.begin (), degs.end ()); + } + + //B(x) ≡ 2C(x) − A(x)C(x)^2 + VI inv (const VI &poly) { + int n = 1; + VI res (1); res[0] = inverse (poly[0], mod); - deg = 1; - for (int t: degs) { - fft::conv (poly, res, t + 1, deg, mod, tmp1); - fft::conv (res, tmp1 + deg, t + 1 - deg, t + 1 - deg, mod, tmp1); - for (int i = 0; i < t + 1 - deg; ++i) { - res[i + deg] = mod - tmp1[i]; + while (n < sz(poly)) { + auto new_res = conv (res, res, n, n, mod); + new_res = conv (poly, new_res, min (2 * n, sz(poly)), sz(new_res), mod); + res.resize (2 * n, 0); + REP(i, 0, 2 * n) { + res[i] = (2ll * res[i] - (i < sz(new_res) ? new_res[i] : 0) + mod) % mod; } - deg = t + 1; + n *= 2; } + res.resize (sz(poly)); + return res; } - // res = ln(poly), poly[0] should be 1 - void log (int poly[], int res[], int n) { - prepare (poly, n); - assert(poly[0] == 1); - inv (poly, tmp2, n); - for (int i = 0; i < n - 1; ++i) { - res[i] = (ll) poly[i + 1] * (i + 1) % mod; - } - fft::conv (res, tmp2, n - 1, n, mod, res); - for (int i = n - 1; i >= 1; --i) { - res[i] = (ll) res[i - 1] * iv[i] % mod; + VI integrate (const VI &poly) { + init (sz(poly)); + VI res (sz(poly), 0); + REP(i, 1, sz (res)) { + res[i] = poly[i - 1] * (ll) iv[i] % mod; } - res[0] = 0; + return res; } - // res = exp(poly), poly[0] should be 0 - void exp (int poly[], int res[], int n) { - prepare (poly, n); - assert(poly[0] == 0); - while (n & n - 1)n += lowbit(n); - if (n == 1) { - res[0] = 1; - return; + VI differentiate (const VI &poly) { + VI res (sz(poly), 0); + REP(i, 0, sz (res) - 1) { + res[i] = poly[i + 1] * ll (i + 1) % mod; } - exp (poly, res, n>>1); - log (res, tmp3, n); - for (int i = 0; i < n; ++i) { - tmp3[i] = poly[i] - tmp3[i]; - if (tmp3[i] < 0) tmp3[i] += mod; - } - if (++tmp3[0] == mod) tmp3[0] = 0; - fft::conv (tmp3, res, n, n, mod, res); - memset (res + n, 0, sizeof (*res) * n); + return res; } - // res = sqrt(poly), poly[0] should be 1 - void sqrt (int poly[], int res[], int n) { - prepare (poly, n); - assert(poly[0] == 1); - while (n & (n - 1)) n += n & (-n); - if (n == 1) { - res[0] = 1; - return; + VI log (const VI &poly) { + auto res = integrate (conv (differentiate (poly), inv (poly), sz(poly), sz(poly), mod)); + res.resize (sz(poly)); + return res; + } + + // g ≡ (1 − ln(g0) + f)g0 + VI exp (const VI &poly) { + int n = 1; + VI res (1, 1); + VI tmp; + while (n < sz(poly)) { + tmp = res; + tmp.resize (2 * n, 0); + tmp = log (tmp); + REP(i, 0, 2 * n) { + tmp[i] = (ll (i == 0) - tmp[i] + (i < sz(poly) ? poly[i] : 0) + mod) % mod; + } + res = conv (res, tmp, n, 2 * n, mod); + res.resize (2 * n, 0); + n *= 2; } - sqrt (poly, res, n>>1); - fill (tmp2 + n / 2, tmp2 + n, 0); - fill (res + n / 2, res + n, 0); - inv (res, tmp2, n); - - fft::conv (poly, tmp2, n, n, mod, tmp1); - for (int i = 0; i < n; i++) { - res[i] = (ll) iv[2] * ((res[i] + tmp1[i]) % mod) % mod; + res.resize (sz(poly)); + return res; + } + + // k < mod + VI power (const VI &poly, const ll k) { + auto low = find_if (all(poly), [] (const int x) { return x != 0; }); + if (low == end (poly))return VI (sz(poly), 0); + ll padding = (low - begin (poly)) * k; + if (padding >= sz(poly))return VI (sz(poly), 0); + VI tmp (low, end (poly)); + ll inv = inverse (*low, mod); + for (auto &x:tmp) x = x * inv % mod; + tmp = log (tmp); + for (auto &x:tmp) x = x * k % mod; + tmp = exp (tmp); + ll pw = fast (inv, -k, mod); + for (auto &x:tmp) x = x * pw % mod; + if (padding) { + VI zeros (padding, 0); + tmp.insert (tmp.begin (), all(zeros)); } + tmp.resize (sz(poly), 0); + return tmp; } + + // TODO: sqrt + + + // TODO: div and mod + + + // TODO: Multi Point Eval } From b237504aa3be9cb45e59e495fff005f30272e82a Mon Sep 17 00:00:00 2001 From: samzhang Date: Tue, 23 Jun 2020 05:40:28 +1200 Subject: [PATCH 05/51] Update Suffix-Automaton.cpp --- .../Suffix-Automaton.cpp" | 61 ++++++++++--------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git "a/\345\255\227\347\254\246\344\270\262/Suffix-Automaton.cpp" "b/\345\255\227\347\254\246\344\270\262/Suffix-Automaton.cpp" index 7493055..4f16f3c 100644 --- "a/\345\255\227\347\254\246\344\270\262/Suffix-Automaton.cpp" +++ "b/\345\255\227\347\254\246\344\270\262/Suffix-Automaton.cpp" @@ -1,55 +1,60 @@ struct SAM { static const int maxn = 300010 * 2; - struct node { - node *nxt[26], *fail; + struct Node { + Node *nxt[26], *fail; int cnt; int len; }; - node *root; + Node *root; int cnt; - node no[maxn]; + Node no[maxn]; - node *newnode() { + Node *newNode () { + memset (&no[cnt], 0, sizeof (Node)); return &no[cnt++]; } - SAM() { + void init () { cnt = 0; - root = newnode(); + root = newNode (); } - void add(const string &s) { - node *cur = root; - REP(i, 0, sz(s)) { - cur = add(cur, s[i] - 'a'); + SAM () { + init (); + } + + void add (const string &s) { + Node *cur = root; + REP(i, 0, sz (s)) { + cur = add (cur, s[i] - 'a'); } } - node *add(node *p, int c) { - node *cur = newnode(); + Node *add (Node *p, int c) { + Node *cur = newNode (); cur->len = p->len + 1; - while(p && !p->nxt[c])p->nxt[c] = cur, p = p->fail; - if(!p) { + while (p && !p->nxt[c])p->nxt[c] = cur, p = p->fail; + if (!p) { cur->fail = root; return cur; } - node *q = p->nxt[c]; - if(q->len == p->len + 1) { + Node *q = p->nxt[c]; + if (q->len == p->len + 1) { cur->fail = q; } else { - node *nq = newnode(); + Node *nq = newNode (); *nq = *q; nq->len = p->len + 1; q->fail = cur->fail = nq; - while(p && p->nxt[c] == q)p->nxt[c] = nq, p = p->fail; + while (p && p->nxt[c] == q)p->nxt[c] = nq, p = p->fail; } return cur; } - void pre(const string &s) { - node *cur = root; - REP(i, 0, sz(s)) { + void pre (const string &s) { + Node *cur = root; + REP(i, 0, sz (s)) { cur = cur->nxt[s[i] - 'a']; cur->cnt++; } @@ -57,20 +62,20 @@ struct SAM { //call pre first //return sum of cnt - void getCnt() { - vector v; + void getCnt () { + vector v; REP(i, 1, cnt) { - v.PB(&no[i]); + v.PB (&no[i]); } - sort(all(v), [](const node *a, const node *b) { + sort (all(v), [] (const Node *a, const Node *b) { return a->len > b->len; }); - REP(i, 0, sz(v)) { + REP(i, 0, sz (v)) { v[i]->fail->cnt += v[i]->cnt; } } - ll getNumOfDistinctSubstrings() { + ll getNumOfDistinctSubstrings () { auto ans = 0; REP(i, 1, cnt)ans += no[i].len - no[i].fail->len; return (ans); From 9f171e96de9cb2e1e116fc315deec0c9c786dd34 Mon Sep 17 00:00:00 2001 From: samzhang Date: Tue, 23 Jun 2020 23:36:41 +1200 Subject: [PATCH 06/51] Update Polynomial.cpp --- "\346\225\260\345\255\246/Polynomial.cpp" | 190 ++++++++++++++++++---- 1 file changed, 160 insertions(+), 30 deletions(-) diff --git "a/\346\225\260\345\255\246/Polynomial.cpp" "b/\346\225\260\345\255\246/Polynomial.cpp" index 45d7f30..ae599d2 100644 --- "a/\346\225\260\345\255\246/Polynomial.cpp" +++ "b/\346\225\260\345\255\246/Polynomial.cpp" @@ -1,8 +1,9 @@ + namespace NTT { const int mod = 998244353, g = 3; void bit_reverse_swap (VI &a) { - int n = sz(a); + int n = sz (a); for (int i = 1, j = n>>1, k; i < n - 1; i++) { if (i < j) swap (a[i], a[j]); for (k = n>>1; j >= k; j -= k, k >>= 1); @@ -35,10 +36,11 @@ namespace NTT { VI _b (begin (b), begin (b) + m); int len = 1; while (len <= n + m - 2) len <<= 1; - while (len != lowbit(len)) len += lowbit(len); + while (len != lowbit (len)) len += lowbit (len); _a.resize (len), _b.resize (len); NTT (_a, 1), NTT (_b, 1); - REP(i, 0, len) _a[i] = (ll) _a[i] * _b[i] % mod; + REP (i, 0, len) + _a[i] = (ll) _a[i] * _b[i] % mod; NTT (_a, -1); _a.resize (n + m - 1); return _a; @@ -49,11 +51,14 @@ namespace NTT { namespace Poly { using NTT::mod; using NTT::conv; - VI iv ({0, 1}); + VI iv ({0, 1}), fac ({1, 1}), facinv ({1, 1}); void init (const int n) { - while (sz(iv) < n) { - iv.emplace_back ((mod - (ll) mod / sz(iv) * iv[mod % sz(iv)] % mod)); + while (sz (iv) <= n) { + ll cur = sz (iv); + iv.emplace_back ((mod - (ll) mod / cur * iv[mod % cur] % mod)); + fac.PB (cur * fac.back () % mod); + facinv.PB ((ll) iv.back () * facinv.back () % mod); } } @@ -62,39 +67,42 @@ namespace Poly { int n = 1; VI res (1); res[0] = inverse (poly[0], mod); - while (n < sz(poly)) { + while (n < sz (poly)) { auto new_res = conv (res, res, n, n, mod); - new_res = conv (poly, new_res, min (2 * n, sz(poly)), sz(new_res), mod); + new_res = conv (poly, new_res, min (2 * n, sz (poly)), sz (new_res), mod); res.resize (2 * n, 0); - REP(i, 0, 2 * n) { - res[i] = (2ll * res[i] - (i < sz(new_res) ? new_res[i] : 0) + mod) % mod; + REP (i, 0, 2 * n) + { + res[i] = (2ll * res[i] - (i < sz (new_res) ? new_res[i] : 0) + mod) % mod; } n *= 2; } - res.resize (sz(poly)); + res.resize (sz (poly)); return res; } VI integrate (const VI &poly) { - init (sz(poly)); - VI res (sz(poly), 0); - REP(i, 1, sz (res)) { + init (sz (poly)); + VI res (sz (poly), 0); + REP (i, 1, sz (res)) + { res[i] = poly[i - 1] * (ll) iv[i] % mod; } return res; } VI differentiate (const VI &poly) { - VI res (sz(poly), 0); - REP(i, 0, sz (res) - 1) { + VI res (sz (poly), 0); + REP (i, 0, sz (res) - 1) + { res[i] = poly[i + 1] * ll (i + 1) % mod; } return res; } VI log (const VI &poly) { - auto res = integrate (conv (differentiate (poly), inv (poly), sz(poly), sz(poly), mod)); - res.resize (sz(poly)); + auto res = integrate (conv (differentiate (poly), inv (poly), sz (poly), sz (poly), mod)); + res.resize (sz (poly)); return res; } @@ -103,47 +111,169 @@ namespace Poly { int n = 1; VI res (1, 1); VI tmp; - while (n < sz(poly)) { + while (n < sz (poly)) { tmp = res; tmp.resize (2 * n, 0); tmp = log (tmp); - REP(i, 0, 2 * n) { - tmp[i] = (ll (i == 0) - tmp[i] + (i < sz(poly) ? poly[i] : 0) + mod) % mod; + REP (i, 0, 2 * n) + { + tmp[i] = (ll (i == 0) - tmp[i] + (i < sz (poly) ? poly[i] : 0) + mod) % mod; } res = conv (res, tmp, n, 2 * n, mod); res.resize (2 * n, 0); n *= 2; } - res.resize (sz(poly)); + res.resize (sz (poly)); return res; } // k < mod VI power (const VI &poly, const ll k) { - auto low = find_if (all(poly), [] (const int x) { return x != 0; }); - if (low == end (poly))return VI (sz(poly), 0); + auto low = find_if (all (poly), [] (const int x) { return x != 0; }); + if (low == end (poly))return VI (sz (poly), 0); ll padding = (low - begin (poly)) * k; - if (padding >= sz(poly))return VI (sz(poly), 0); + if (padding >= sz (poly))return VI (sz (poly), 0); VI tmp (low, end (poly)); ll inv = inverse (*low, mod); for (auto &x:tmp) x = x * inv % mod; tmp = log (tmp); - for (auto &x:tmp) x = x * k % mod; + for (auto &x:tmp) x = x * (k % mod) % mod; tmp = exp (tmp); ll pw = fast (inv, -k, mod); for (auto &x:tmp) x = x * pw % mod; if (padding) { VI zeros (padding, 0); - tmp.insert (tmp.begin (), all(zeros)); + tmp.insert (tmp.begin (), all (zeros)); } - tmp.resize (sz(poly), 0); + tmp.resize (sz (poly), 0); return tmp; } - // TODO: sqrt + ll modSqrt (ll a, ll p) { + auto isSquare = [&] (ll a, ll p) { + return fast (a, (p - 1) / 2, p) == 1; + }; + if (a == 0) return 0; + if (p == 2) return a; + if (!isSquare (a, p)) return -1; + ll b = 2; + while (isSquare ((b * b - a + p) % p, p)) b++; + ll w = (b * b - a + p) % p; + + auto mul = [&] (PLL u, PLL v) { + ll a = (u.first * v.first + u.second * v.second % p * w) % p; + ll b = (u.first * v.second + u.second * v.first) % p; + return MP (a, b); + }; + + // (b + sqrt(b^2-a))^(p+1)/2 + ll e = (p + 1) / 2; + auto ret = MP (1, 0); + auto v = MP (b, 1); + while (e > 0) { + if (e & 1) ret = mul (ret, v); + v = mul (v, v); + e /= 2; + } + return ret.first; + } + VI sqrt (VI poly) { + const int len = sz (poly); + init (2); + const auto low = find_if (all (poly), [] (const int x) { return x != 0; }); + if (low == end (poly))return VI (sz (poly), 0); + int padding = (low - begin (poly)); + if (padding & 1) return VI (1, -1); + padding >>= 1; + poly = VI (low, end (poly)); + VI res (1); + res[0] = modSqrt (poly[0], mod); + if (res[0] == -1)return res; + res[0] = min (res[0], mod - res[0]); + int n = 1; + while (n < len) { + n *= 2; + res.resize (n, 0); + auto other = conv (poly, inv (res), min (2 * n, sz (poly)), n, mod); + REP (i, 0, n) + { + res[i] = (res[i] + other[i]) * ll (iv[2]) % mod; + } + } + if (padding) { + VI zeros (padding, 0); + res.insert (res.begin (), all (zeros)); + } + res.resize (len, 0); + return res; + } + + // + pair divmod (VI f, VI g) { + auto removeTrailingZeros = [] (VI &poly) { + while (sz (poly) and poly.back () == 0)poly.pop_back (); + }; + removeTrailingZeros (f); + removeTrailingZeros (g); + assert (sz (g) > 0); + const int n = sz (f) - 1, m = sz (g) - 1; + if (n < m)return MP (VI (), f); + auto rev = [] (VI poly) { + reverse (all (poly)); + return poly; + }; + auto rg = rev (g); + rg.resize (n, 0); + auto q = (conv (rev (f), inv (rg), sz (f), sz (rg))); + q.resize (n - m + 1, 0); + q = rev (q); + auto prod = conv (g, q, sz (g), sz (q)); + auto r = f; + REP (i, 0, sz (r)) + r[i] = (r[i] - prod[i] + mod) % mod; + r.resize (m, 0); + removeTrailingZeros (r); + return MP (q, r); + } + + VI shift (const VI &poly, const int n) { + init (sz (poly)); + VI a (sz (poly)), b (sz (poly)); + REP (i, 0, sz (a)) + a[i] = (ll) fac[i] * poly[i] % mod; + for (int i = 0, prod = 1; i < sz (poly); i++, prod = (ll) prod * n % mod) { + b[i] = (ll) facinv[i] * prod % mod; + } + VI res (sz (poly)); + reverse (all (b)); + a = conv (a, b, sz (a), sz (b)); + REP (i, 0, sz (res)) + { + res[i] = (ll) a[i + sz (poly) - 1] * facinv[i] % mod; + } + return res; + } + + + // x(x-1)(x-2)...(x-(n-1)) + VI signedFirstStirling (const int n) { + if (n == 0) return VI ({1}); + else { + VI a = signedFirstStirling (n / 2); + VI b = shift (a, mod - n / 2); + a = conv (a, b, sz (a), sz (b)); + if (n & 1) { + a.PB (0); + RREP (i, n, 0) + { + a[i] = (ll (a[i]) * (mod - (n - 1)) + (i > 0 ? a[i - 1] : 0)) % mod; + } + } + return a; + } + } - // TODO: div and mod // TODO: Multi Point Eval From 84137345293c09ed7b45c4f8cd3381688f5bf6c1 Mon Sep 17 00:00:00 2001 From: samzhang Date: Thu, 25 Jun 2020 01:51:44 +1200 Subject: [PATCH 07/51] Update Polynomial.cpp --- "\346\225\260\345\255\246/Polynomial.cpp" | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git "a/\346\225\260\345\255\246/Polynomial.cpp" "b/\346\225\260\345\255\246/Polynomial.cpp" index ae599d2..833f3d7 100644 --- "a/\346\225\260\345\255\246/Polynomial.cpp" +++ "b/\346\225\260\345\255\246/Polynomial.cpp" @@ -1,7 +1,11 @@ namespace NTT { const int mod = 998244353, g = 3; - + // 1004535809 3 + // 167772161 3 + // 469762049 3 + // 924844033 5 + // 104857601 3 void bit_reverse_swap (VI &a) { int n = sz (a); for (int i = 1, j = n>>1, k; i < n - 1; i++) { From 1212cace43c6f3e3d80896465293ec484684c87c Mon Sep 17 00:00:00 2001 From: samzhang Date: Thu, 25 Jun 2020 06:01:45 +1200 Subject: [PATCH 08/51] Update Polynomial.cpp --- "\346\225\260\345\255\246/Polynomial.cpp" | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git "a/\346\225\260\345\255\246/Polynomial.cpp" "b/\346\225\260\345\255\246/Polynomial.cpp" index 833f3d7..f340be8 100644 --- "a/\346\225\260\345\255\246/Polynomial.cpp" +++ "b/\346\225\260\345\255\246/Polynomial.cpp" @@ -2,6 +2,7 @@ namespace NTT { const int mod = 998244353, g = 3; // 1004535809 3 + // 1005060097 5 // 167772161 3 // 469762049 3 // 924844033 5 @@ -278,6 +279,18 @@ namespace Poly { } } + VI secondStirling (const int n) { + init (n); + VI a (begin (facinv), begin (facinv) + n + 1), b (begin (facinv), begin (facinv) + n + 1); + ll cur = 1; + REP(i, 0, n + 1) { + if (i & 1)b[i] = mod - b[i]; + a[i] = MOD (a[i] * fast (i, n, mod), mod); + } + auto res = conv (a, b, n + 1, n + 1); + res.resize (n + 1); + return res; + } // TODO: Multi Point Eval From 2e4a314471309c871677f0555b423c3698f20a21 Mon Sep 17 00:00:00 2001 From: samzhang Date: Thu, 25 Jun 2020 16:39:57 +1200 Subject: [PATCH 09/51] Update Polynomial.cpp --- "\346\225\260\345\255\246/Polynomial.cpp" | 41 +++++++++-------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git "a/\346\225\260\345\255\246/Polynomial.cpp" "b/\346\225\260\345\255\246/Polynomial.cpp" index f340be8..1df7370 100644 --- "a/\346\225\260\345\255\246/Polynomial.cpp" +++ "b/\346\225\260\345\255\246/Polynomial.cpp" @@ -76,8 +76,7 @@ namespace Poly { auto new_res = conv (res, res, n, n, mod); new_res = conv (poly, new_res, min (2 * n, sz (poly)), sz (new_res), mod); res.resize (2 * n, 0); - REP (i, 0, 2 * n) - { + REP (i, 0, 2 * n) { res[i] = (2ll * res[i] - (i < sz (new_res) ? new_res[i] : 0) + mod) % mod; } n *= 2; @@ -89,8 +88,7 @@ namespace Poly { VI integrate (const VI &poly) { init (sz (poly)); VI res (sz (poly), 0); - REP (i, 1, sz (res)) - { + REP (i, 1, sz (res)) { res[i] = poly[i - 1] * (ll) iv[i] % mod; } return res; @@ -98,8 +96,7 @@ namespace Poly { VI differentiate (const VI &poly) { VI res (sz (poly), 0); - REP (i, 0, sz (res) - 1) - { + REP (i, 0, sz (res) - 1) { res[i] = poly[i + 1] * ll (i + 1) % mod; } return res; @@ -120,8 +117,7 @@ namespace Poly { tmp = res; tmp.resize (2 * n, 0); tmp = log (tmp); - REP (i, 0, 2 * n) - { + REP (i, 0, 2 * n) { tmp[i] = (ll (i == 0) - tmp[i] + (i < sz (poly) ? poly[i] : 0) + mod) % mod; } res = conv (res, tmp, n, 2 * n, mod); @@ -195,14 +191,13 @@ namespace Poly { VI res (1); res[0] = modSqrt (poly[0], mod); if (res[0] == -1)return res; - res[0] = min (res[0], mod - res[0]); + upmin (res[0], mod - res[0]); int n = 1; while (n < len) { n *= 2; res.resize (n, 0); auto other = conv (poly, inv (res), min (2 * n, sz (poly)), n, mod); - REP (i, 0, n) - { + REP (i, 0, n) { res[i] = (res[i] + other[i]) * ll (iv[2]) % mod; } } @@ -215,7 +210,7 @@ namespace Poly { } // - pair divmod (VI f, VI g) { + pair divmod (VI f, VI g) { auto removeTrailingZeros = [] (VI &poly) { while (sz (poly) and poly.back () == 0)poly.pop_back (); }; @@ -230,13 +225,12 @@ namespace Poly { }; auto rg = rev (g); rg.resize (n, 0); - auto q = (conv (rev (f), inv (rg), sz (f), sz (rg))); + auto q = (conv (rev (f), inv (rg), sz (f), sz (rg), mod)); q.resize (n - m + 1, 0); q = rev (q); - auto prod = conv (g, q, sz (g), sz (q)); + auto prod = conv (g, q, sz (g), sz (q), mod); auto r = f; - REP (i, 0, sz (r)) - r[i] = (r[i] - prod[i] + mod) % mod; + REP (i, 0, sz (r))r[i] = (r[i] - prod[i] + mod) % mod; r.resize (m, 0); removeTrailingZeros (r); return MP (q, r); @@ -245,16 +239,14 @@ namespace Poly { VI shift (const VI &poly, const int n) { init (sz (poly)); VI a (sz (poly)), b (sz (poly)); - REP (i, 0, sz (a)) - a[i] = (ll) fac[i] * poly[i] % mod; + REP (i, 0, sz (a))a[i] = (ll) fac[i] * poly[i] % mod; for (int i = 0, prod = 1; i < sz (poly); i++, prod = (ll) prod * n % mod) { b[i] = (ll) facinv[i] * prod % mod; } VI res (sz (poly)); reverse (all (b)); - a = conv (a, b, sz (a), sz (b)); - REP (i, 0, sz (res)) - { + a = conv (a, b, sz (a), sz (b), mod); + REP (i, 0, sz (res)) { res[i] = (ll) a[i + sz (poly) - 1] * facinv[i] % mod; } return res; @@ -267,11 +259,10 @@ namespace Poly { else { VI a = signedFirstStirling (n / 2); VI b = shift (a, mod - n / 2); - a = conv (a, b, sz (a), sz (b)); + a = conv (a, b, sz (a), sz (b), mod); if (n & 1) { a.PB (0); - RREP (i, n, 0) - { + RREP (i, n, 0) { a[i] = (ll (a[i]) * (mod - (n - 1)) + (i > 0 ? a[i - 1] : 0)) % mod; } } @@ -287,7 +278,7 @@ namespace Poly { if (i & 1)b[i] = mod - b[i]; a[i] = MOD (a[i] * fast (i, n, mod), mod); } - auto res = conv (a, b, n + 1, n + 1); + auto res = conv (a, b, n + 1, n + 1, mod); res.resize (n + 1); return res; } From e6c759a31b3886951da776d4319f3a4ac1a8767a Mon Sep 17 00:00:00 2001 From: samzhang Date: Thu, 25 Jun 2020 20:00:09 +1200 Subject: [PATCH 10/51] Update Polynomial.cpp --- "\346\225\260\345\255\246/Polynomial.cpp" | 1 - 1 file changed, 1 deletion(-) diff --git "a/\346\225\260\345\255\246/Polynomial.cpp" "b/\346\225\260\345\255\246/Polynomial.cpp" index 1df7370..630dffd 100644 --- "a/\346\225\260\345\255\246/Polynomial.cpp" +++ "b/\346\225\260\345\255\246/Polynomial.cpp" @@ -273,7 +273,6 @@ namespace Poly { VI secondStirling (const int n) { init (n); VI a (begin (facinv), begin (facinv) + n + 1), b (begin (facinv), begin (facinv) + n + 1); - ll cur = 1; REP(i, 0, n + 1) { if (i & 1)b[i] = mod - b[i]; a[i] = MOD (a[i] * fast (i, n, mod), mod); From 0c347cc343cfd92dba20a4c4bd563d2b57d028c0 Mon Sep 17 00:00:00 2001 From: samzhang Date: Fri, 26 Jun 2020 03:32:16 +1200 Subject: [PATCH 11/51] Update Fast-Fourier-Transform.cpp --- "\346\225\260\345\255\246/Fast-Fourier-Transform.cpp" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\346\225\260\345\255\246/Fast-Fourier-Transform.cpp" "b/\346\225\260\345\255\246/Fast-Fourier-Transform.cpp" index 48b7c15..13f1fa1 100644 --- "a/\346\225\260\345\255\246/Fast-Fourier-Transform.cpp" +++ "b/\346\225\260\345\255\246/Fast-Fourier-Transform.cpp" @@ -81,7 +81,7 @@ namespace fft { VLL conv (const VI &a, const VI &b) { int n = a.size (), m = b.size (), L = 0, s = 1; for (; s <= n + m - 2; s <<= 1, ++L); - s >>= 1, --L; + if (L > 2) s >>= 1, --L; init (L); for (int i = 0; i < s; ++i) { A[i].x = (i<<1) < n ? a[i<<1] : 0; From d3a3c11d43da1b489e6ab2feb3958c4b17dedcd4 Mon Sep 17 00:00:00 2001 From: samzhang Date: Sun, 28 Jun 2020 12:14:26 +1200 Subject: [PATCH 12/51] Update String-Hash.cpp --- .../String-Hash.cpp" | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git "a/\345\255\227\347\254\246\344\270\262/String-Hash.cpp" "b/\345\255\227\347\254\246\344\270\262/String-Hash.cpp" index 214cd67..4f7dee2 100644 --- "a/\345\255\227\347\254\246\344\270\262/String-Hash.cpp" +++ "b/\345\255\227\347\254\246\344\270\262/String-Hash.cpp" @@ -7,61 +7,61 @@ struct Hashing { array seed, mod; array, 2> hs, pw; - Hashing(array seed = {28, 31}, - array mod = {1000000007, 1000173169}) : seed(seed), mod(mod) { - init(); + Hashing (array seed = {28, 31}, + array mod = {1000000007, 1000173169}) : seed (seed), mod (mod) { + init (); } - void init() { + void init () { hs[0] = hs[1] = {0}; pw[0] = pw[1] = {1}; } - void push(ll ch) { - assert(ch != 0); - for(int i = 0; i < 2; i++) { - pw[i].push_back(pw[i].back() * seed[i] % mod[i]); - hs[i].push_back((hs[i].back() * seed[i] + ch) % mod[i]); + void push (ll ch) { + assert (ch != 0); + for (int i = 0; i < 2; i++) { + pw[i].push_back (pw[i].back () * seed[i] % mod[i]); + hs[i].push_back ((hs[i].back () * seed[i] + ch) % mod[i]); } } - void pop() { - assert(size() > 1); - for(int i = 0; i < 2; i++) { - pw[i].pop_back(); - hs[i].pop_back(); + void pop () { + assert (size () > 1); + for (int i = 0; i < 2; i++) { + pw[i].pop_back (); + hs[i].pop_back (); } } template - void build(T begin, T end) { - init(); - while(begin != end) { - push(*(begin++)); + void build (T begin, T end) { + init (); + while (begin != end) { + push (*(begin++)); } } template - void push(T begin, T end) { - while(begin != end) { - push(*(begin++)); + void push (T begin, T end) { + while (begin != end) { + push (*(begin++)); } } - array hash(int l, int r) { + ll hash (int l, int r) { l--; - assert(l <= r and r <= size()); + assert (l <= r and r <= size ()); array ans{0, 0}; - if(l >= r)return ans; - for(int i = 0; i < 2; i++) { + if (l >= r)return (ans[0]<<32) + ans[1]; + for (int i = 0; i < 2; i++) { ans[i] = (hs[i][r] - hs[i][l] * pw[i][r - l]) % mod[i]; - if(ans[i] < 0)ans[i] += mod[i]; + if (ans[i] < 0)ans[i] += mod[i]; } - return ans; + return (ans[0]<<32) + ans[1]; } - int size() { - return hs[0].size() - 1; + int size () { + return hs[0].size () - 1; } }; From 3dead465cd752719099cffa29a762ead958240a3 Mon Sep 17 00:00:00 2001 From: samzhang Date: Wed, 1 Jul 2020 02:03:47 +1200 Subject: [PATCH 13/51] Update Pollard-Rho&MillerRabin.cpp --- .../Pollard-Rho&MillerRabin.cpp" | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git "a/\346\225\260\345\255\246/Pollard-Rho&MillerRabin.cpp" "b/\346\225\260\345\255\246/Pollard-Rho&MillerRabin.cpp" index 14f6e60..9e3efd0 100644 --- "a/\346\225\260\345\255\246/Pollard-Rho&MillerRabin.cpp" +++ "b/\346\225\260\345\255\246/Pollard-Rho&MillerRabin.cpp" @@ -3,12 +3,12 @@ struct Primality { using pii = std::pair; template - T gcd(T a, T b) { - return !b ? a : gcd(b, a % b); + T gcd (T a, T b) { + return !b ? a : gcd (b, a % b); } - inline int64 mul_mod(int64 a, int64 b, int64 mod) { - if (mod < int(1e9)) return a * b % mod; + inline int64 mul_mod (int64 a, int64 b, int64 mod) { + if (mod < int (1e9)) return a * b % mod; int64 k = (int64) ((long double) a * b / mod); int64 res = a * b - k * mod; res %= mod; @@ -16,55 +16,55 @@ struct Primality { return res; } - int64 pow_mod(int64 a, int64 n, int64 m) { + int64 pow_mod (int64 a, int64 n, int64 m) { int64 res = 1; for (a %= m; n; n >>= 1) { - if (n & 1) res = mul_mod(res, a, m); - a = mul_mod(a, a, m); + if (n & 1) res = mul_mod (res, a, m); + a = mul_mod (a, a, m); } return res; } public: // 用miller rabin素数测试判断n是否为质数 - bool is_prime(int64 n) { + bool is_prime (int64 n) { if (n <= 1) return false; if (n <= 3) return true; - if (~n & 1) return false; - const int u[] = {2, 3, 5, 7, 325, 9375, 28178, 450775, 9780504, 1795265022, 0}; + if (n % 2 == 0)return false; + const int u[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022, 0}; int64 e = n - 1, a, c = 0; // 原理:http://miller-rabin.appspot.com/ - while (~e & 1) e >>= 1, ++c; + while (!(e & 1)) e >>= 1, ++c; for (int i = 0; u[i]; ++i) { - if (n <= u[i]) return true; - a = pow_mod(u[i], e, n); + if (u[i] % n == 0) continue; + a = pow_mod (u[i], e, n); if (a == 1) continue; for (int j = 1; a != n - 1; ++j) { if (j == c) return false; - a = mul_mod(a, a, n); + a = mul_mod (a, a, n); } } return true; } // 求一个小于n的因数,期望复杂度为O(n^0.25),当n为非合数时返回n本身 - int64 pollard_rho(int64 n) { - if (n <= 3 || is_prime(n)) return n; // 保证n为合数时可去掉这行 + int64 pollard_rho (int64 n) { + if (n <= 3 || is_prime (n)) return n; // 保证n为合数时可去掉这行 while (1) { int i = 1, cnt = 2; - int64 x = rand() % n, y = x, c = rand() % n; + int64 x = rand () % n, y = x, c = rand () % n; if (!c || c == n - 2) ++c; do { - int64 u = gcd(n - x + y, n); + int64 u = gcd (n - x + y, n); if (u > 1 && u < n) return u; if (++i == cnt) y = x, cnt <<= 1; - x = (c + mul_mod(x, x, n)) % n; + x = (c + mul_mod (x, x, n)) % n; } while (x != y); } return n; } // 使用rho方法对n做质因数分解,建议先筛去小质因数后再用此函数 - std::vector factorize(int64 n) { + std::vector factorize (int64 n) { static const int sp[25] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97}; std::vector fac; @@ -72,41 +72,41 @@ struct Primality { if (n % sp[i]) continue; int c = 0; while (n % sp[i] == 0) n /= sp[i], ++c; - fac.emplace_back(sp[i], c); + fac.emplace_back (sp[i], c); } std::vector u; - if (n > 1) u.push_back(n); - for (size_t i = 0; i < u.size(); ++i) { - int64 x = pollard_rho(u[i]); + if (n > 1) u.push_back (n); + for (size_t i = 0; i < u.size (); ++i) { + int64 x = pollard_rho (u[i]); if (x == u[i]) continue; u[i--] /= x; - u.push_back(x); + u.push_back (x); } - std::sort(u.begin(), u.end()); - for (size_t i = 0, j, m = u.size(); i < m; i = j) { + std::sort (u.begin (), u.end ()); + for (size_t i = 0, j, m = u.size (); i < m; i = j) { for (j = i; j < m && u[i] == u[j]; ++j); - fac.emplace_back(u[i], j - i); + fac.emplace_back (u[i], j - i); } return fac; } - std::vector divisors(int64 n) { + std::vector divisors (int64 n) { if (n == 1) return {1}; - auto fac = factorize(n); - int m = fac.size(); + auto fac = factorize (n); + int m = fac.size (); std::vector ds; - std::function dfs = [&](int d, int64 now) { + std::function dfs = [&] (int d, int64 now) { if (d == m) { - ds.emplace_back(now); + ds.emplace_back (now); return; } for (int i = 0, u = fac[d].second; i <= u; ++i) { - dfs(d + 1, now); + dfs (d + 1, now); now *= fac[d].first; } }; - dfs(0, 1); - std::sort(ds.begin(), ds.end()); + dfs (0, 1); + std::sort (ds.begin (), ds.end ()); return ds; } } pf; From 4cf3dc84f3489f13fb808cb47b0697c355bf8946 Mon Sep 17 00:00:00 2001 From: samzhang Date: Wed, 1 Jul 2020 06:56:09 +1200 Subject: [PATCH 14/51] fix --- .../Suffix-Array.cpp" | 73 ++++++++----------- .../Suffix-Automaton.cpp" | 2 +- 2 files changed, 33 insertions(+), 42 deletions(-) diff --git "a/\345\255\227\347\254\246\344\270\262/Suffix-Array.cpp" "b/\345\255\227\347\254\246\344\270\262/Suffix-Array.cpp" index cd74ccc..30158f3 100644 --- "a/\345\255\227\347\254\246\344\270\262/Suffix-Array.cpp" +++ "b/\345\255\227\347\254\246\344\270\262/Suffix-Array.cpp" @@ -1,46 +1,41 @@ template class SuffixArray { public: - void build_SA(const T &str, vector &sa, vector &rk) { + void build_SA (const T &str, vector &sa, vector &rk) { const int len = sz(str); - vector > ord[2] = {vector < pair < PII, int >> (len), vector < pair < PII, int >> (len)}; - sa = std::vector(len); - rk = std::vector(len); - REP(i, 0, len) - { - ord[1][i] = MP(MP(str[i], 0), i); + vector> ord[2] = {vector> (len), vector> (len)}; + sa = std::vector (len); + rk = std::vector (len); + REP(i, 0, len) { + ord[1][i] = MP (MP (str[i], 0), i); } for (int b = 0;; b++) { int cur = b % 2; - sort(all(ord[cur ^ 1])); - REP(i, 0, len) - { + sort (all(ord[cur ^ 1])); + REP(i, 0, len) { rk[ord[cur ^ 1][i].se] = i == 0 ? 0 : (rk[ord[cur ^ 1][i - 1].se] + (ord[cur ^ 1][i - 1].fi != ord[cur ^ 1][i].fi)); } if (rk[ord[cur ^ 1][len - 1].se] == len - 1)break; - REP(i, 0, len) - ord[cur][i] = MP(MP(rk[i], (i + twop(b) < len) ? rk[i + twop(b)] : -inf), i); + REP(i, 0, len)ord[cur][i] = MP (MP (rk[i], (i + twop (b) < len) ? rk[i + twop (b)] : -1e9), i); } - REP(i, 0, len) - sa[rk[i]] = i; + REP(i, 0, len)sa[rk[i]] = i; } - vector > st; + vector> st; - void build_height(const T &str, const vector &sa, const vector &rk, vector &height) { - height = std::vector(sz(str), 0); + void build_height (const T &str, const vector &sa, const vector &rk, vector &height) { + height = std::vector (sz(str), 0); const int len = sz(str); - REP(i, 0, len) - { + REP(i, 0, len) { if (rk[i] == 0)continue; while (i + height[rk[i]] < len && sa[rk[i] - 1] + height[rk[i]] < len && str[i + height[rk[i]]] == str[sa[rk[i] - 1] + height[rk[i]]]) { height[rk[i]]++; } if (i != len - 1) { - height[rk[i + 1]] = max(0, height[rk[i]] - 1); + height[rk[i + 1]] = max (0, height[rk[i]] - 1); } } } @@ -48,44 +43,40 @@ class SuffixArray { T str; vector sa, rk; - void init(const T &s, bool getHeight = 0) { + void init (const T &s, bool getHeight = 0) { str = s; - build_SA(str, sa, rk); + build_SA (str, sa, rk); if (getHeight) { - st = vector < vector < int >> (ceil(log2(sz(s)) + eps), vector(sz(s))); - build_height(str, sa, rk, st[0]); - REP(i, 0, sz(st) - 1) - { - REP(j, 0, sz(s) - twop(i)) - { - st[i + 1][j] = min(st[i][j], st[i][j + twop(i)]); + st = vector> (ceil (log2 (sz(s)) + 1e-2), vector (sz(s))); + build_height (str, sa, rk, st[0]); + REP(i, 0, sz (st) - 1) { + REP(j, 0, sz (s) - twop (i)) { + st[i + 1][j] = min (st[i][j], st[i][j + twop (i)]); } } } } - void test() { - REP(i, 0, sz(str)) - { - cout << (i) << " "; - REP(j, sa[i], sz(str)) - { + void test () { + REP(i, 0, sz (str)) { + cout<<(i)<<" "; + REP(j, sa[i], sz (str)) { if (str[j] < 0)break; - cout << char(str[j]); + cout< r)swap(l, r); + if (l > r)swap (l, r); l++; - int lvl = floor(log2(r - l + 1) + eps); - return min(st[lvl][l], st[lvl][r - twop(lvl) + 1]); + int lvl = floor (log2 (r - l + 1)); + return min (st[lvl][l], st[lvl][r - twop (lvl) + 1]); } } diff --git "a/\345\255\227\347\254\246\344\270\262/Suffix-Automaton.cpp" "b/\345\255\227\347\254\246\344\270\262/Suffix-Automaton.cpp" index 4f16f3c..ca0af2e 100644 --- "a/\345\255\227\347\254\246\344\270\262/Suffix-Automaton.cpp" +++ "b/\345\255\227\347\254\246\344\270\262/Suffix-Automaton.cpp" @@ -76,7 +76,7 @@ struct SAM { } ll getNumOfDistinctSubstrings () { - auto ans = 0; + ll ans = 0; REP(i, 1, cnt)ans += no[i].len - no[i].fail->len; return (ans); } From d5d34d24d69434ec4ce810e2d2ac78763eb33e26 Mon Sep 17 00:00:00 2001 From: samzhang Date: Wed, 8 Jul 2020 01:11:31 +0800 Subject: [PATCH 15/51] Create KM.cpp --- "\345\233\276\350\256\272/KM.cpp" | 73 +++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 "\345\233\276\350\256\272/KM.cpp" diff --git "a/\345\233\276\350\256\272/KM.cpp" "b/\345\233\276\350\256\272/KM.cpp" new file mode 100644 index 0000000..3de9584 --- /dev/null +++ "b/\345\233\276\350\256\272/KM.cpp" @@ -0,0 +1,73 @@ +// 二分图最 "大" 权 "完美" 匹配,从 0 开始 +// 不存在的边设成-inf +// sy[i] 表示 *右侧* 的 i 的对象 +struct KM { + typedef long long cost_t; + static const int N = 1000; + static const cost_t inf = 1e9; + cost_t lx[N], ly[N], sl[N]; + int px[N], py[N], sy[N], fa[N], n; + + void aug (int v) { + sy[v] = py[v]; + if (px[sy[v]] != -2) aug (px[sy[v]]); + } + + bool find (int v, const cost_t w[][N]) { + for (int i = 0; i < n; ++i) + if (!~py[i]) { + if (sl[i] > lx[v] + ly[i] - w[v][i]) { + sl[i] = lx[v] + ly[i] - w[v][i]; + fa[i] = v; + } + if (lx[v] + ly[i] == w[v][i]) { + py[i] = v; + if (!~sy[i]) { + aug (i); + return 1; + } + if (~px[sy[i]]) continue; + px[sy[i]] = i; + if (find (sy[i], w)) return 1; + } + } + return 0; + } + + cost_t gao (int _n, const cost_t w[][N], cost_t m = inf) { + n = _n; + std::fill (sy, sy + n, -1); + std::fill (ly, ly + n, 0); + for (int i = 0; i < n; ++i) lx[i] = *std::max_element (w[i], w[i] + n); + for (int i (0), flag; i < n; ++i) { + for (int j = 0; j < n; ++j)px[j] = py[j] = -1, sl[j] = inf; + px[i] = -2; + if (find (i, w)) continue; + for (flag = 0, m = inf; !flag; m = inf) { + for (int j = 0; j < n; ++j) if (!~py[j]) m = std::min (m, sl[j]); + for (int j = 0; j < n; ++j) { + if (~px[j]) lx[j] -= m; + if (~py[j]) ly[j] += m; + else sl[j] -= m; + } + for (int j = 0; j < n; ++j) + if (!~py[j] && !sl[j]) { + py[j] = fa[j]; + if (!~sy[j]) { + aug (j); + flag = 1; + break; + } + px[sy[j]] = j; + if (find (sy[j], w)) { + flag = 1; + break; + } + } + } + } + cost_t ret (0); + for (int i = 0; i < n; ++i) ret += w[sy[i]][i]; + return ret; + } +} km; From 1342d11aa5bf573d55565a4e9b028052126b994b Mon Sep 17 00:00:00 2001 From: samzhang Date: Thu, 9 Jul 2020 07:49:31 +0800 Subject: [PATCH 16/51] Update Gaussian-Elimination.cpp --- .../Gaussian-Elimination.cpp" | 47 ++++++++++++------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git "a/\346\225\260\345\255\246/Gaussian-Elimination.cpp" "b/\346\225\260\345\255\246/Gaussian-Elimination.cpp" index 8a72b16..22b079f 100644 --- "a/\346\225\260\345\255\246/Gaussian-Elimination.cpp" +++ "b/\346\225\260\345\255\246/Gaussian-Elimination.cpp" @@ -24,25 +24,38 @@ bool gauss(flt a[][MAXN], flt b[], int n) { return 1; } -int det_mod(int n, int mod, vector > mat) { - for (int i = 0; i < n; ++i) { - for (int j = 0; j < n; ++j) { - mat[i][j] %= mod; - } - } + +// mod 可为合数 +int det_mod (const int n, const int mod, vector> mat) { + assert(mod > 0); + assert(sz (mat) == n and sz (mat[0]) == n); + for (auto &row:mat) + for (auto &elem:row) + elem = MOD (elem, mod); ll ret = 1; - for (int i = 0; i < n; ++i) { - for (int j = i + 1; j < n; ++j) - for (; mat[j][i]; ret = -ret) { - ll t = mat[i][i] / mat[j][i]; - for (int k = i; k < n; ++k) { - mat[i][k] = (mat[i][k] - mat[j][k] * t) % mod; - std::swap(mat[j][k], mat[i][k]); + for (int col = 0; col < n; col++) { + for (int row = col + 1; row < n; row++) { + if (mat[row][col]) { + int co = inverse (mat[row][col] / gcd (mat[row][col], mod), mod); + if (co != 1) { + for (auto &v:mat[row]) { + v = (ll) v * co % mod; + } + ret = ret * inverse (co, mod) % mod; + } + while (mat[row][col] != 0) { + ll t = mat[col][col] / mat[row][col]; + if (t) + for (int k = col; k < n; ++k) { + mat[col][k] = MOD (mat[col][k] - mat[row][k] * t, mod); + } + swap (mat[col], mat[row]); + ret *= -1; } } - if (mat[i][i] == 0) return 0; - ret = ret * mat[i][i] % mod; + } + ret *= mat[col][col]; + ret %= mod; } - if (ret < 0) ret += mod; - return (int) ret; + return MOD (ret, mod); } From 906eec8de44806e901a31fcb591b14f2d8a4ef2d Mon Sep 17 00:00:00 2001 From: samzhang Date: Sun, 12 Jul 2020 16:43:18 +0800 Subject: [PATCH 17/51] =?UTF-8?q?Update=20=E5=B8=B8=E8=A7=81=E9=94=99?= =?UTF-8?q?=E8=AF=AF.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\345\270\270\350\247\201\351\224\231\350\257\257.md" | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git "a/\345\270\270\350\247\201\351\224\231\350\257\257.md" "b/\345\270\270\350\247\201\351\224\231\350\257\257.md" index bdaa862..181d819 100644 --- "a/\345\270\270\350\247\201\351\224\231\350\257\257.md" +++ "b/\345\270\270\350\247\201\351\224\231\350\257\257.md" @@ -20,6 +20,6 @@ - 及时取模 - 取消同步后混用 - 二分时有负数要写 `l+(r-l)/2` - - +- 谨慎复制粘贴 + From 18d832081cad24fea997357701717807d7418305 Mon Sep 17 00:00:00 2001 From: samzhang Date: Sun, 12 Jul 2020 16:43:21 +0800 Subject: [PATCH 18/51] Update FWT.cpp --- "\346\225\260\345\255\246/FWT.cpp" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\346\225\260\345\255\246/FWT.cpp" "b/\346\225\260\345\255\246/FWT.cpp" index 171cd1a..0199eee 100644 --- "a/\346\225\260\345\255\246/FWT.cpp" +++ "b/\346\225\260\345\255\246/FWT.cpp" @@ -9,7 +9,7 @@ void FWT(int a[], int n) { //or:a[i+j+d]=x+y; } } - +1 void UFWT(int a[], int n) { for (int d = 1; d < n; d <<= 1) //你甚至可以RANDOMSHUFFLE for (int m = d << 1, i = 0; i < n; i += m) From 827fe3de24b4afc1b701c9a951d6e39099851265 Mon Sep 17 00:00:00 2001 From: samzhang Date: Sat, 18 Jul 2020 17:54:21 +0800 Subject: [PATCH 19/51] Create PrimeCounting.cpp --- "\346\225\260\345\255\246/PrimeCounting.cpp" | 55 ++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 "\346\225\260\345\255\246/PrimeCounting.cpp" diff --git "a/\346\225\260\345\255\246/PrimeCounting.cpp" "b/\346\225\260\345\255\246/PrimeCounting.cpp" new file mode 100644 index 0000000..1746cd9 --- /dev/null +++ "b/\346\225\260\345\255\246/PrimeCounting.cpp" @@ -0,0 +1,55 @@ +struct PrimeCounting { +private: + void EratosthenesSieve (const int n, VLL &primes) { + vector numbers (n + 1); + for (ll i = 2; i <= n; i++) { + if (!numbers[i]) { + primes.PB (i); + for (ll j = i * i; j <= n; j += i)numbers[j] = 1; + } + } + } + + void compute () { + for (auto p:primes) { + for (int i = 0; i < sz(quotient); i++) { + if (p * p > quotient[i])break; + // 卡常时如不需要 mod 可以去掉 + sum[i] = MOD (sum[i] - (sum[get_id (divisor[i] * p)] - sum[get_id ((n / (p - 1)))]), mod); + } + } + } + + inline int get_id (const ll &divisor) { + if (n / divisor <= lim) { + return id[0][n / divisor]; + } else { + return id[1][divisor]; + } + } + +public: + VI id[2]; + VLL quotient, sum, divisor, primes; + const ll lim, n, mod; + + // 传入积性函数前缀和函数 prefix_f + // 答案在 sum[0] + template + PrimeCounting (const ll n, T prefix_f, const ll mod):n (n), lim (sqrt (n)), mod (mod) { + id[0] = id[1] = VI (lim + 1, 0); + for (ll i = 1; i <= n; i = n / (n / i) + 1) { + quotient.emplace_back (n / i); + divisor.emplace_back (i); + sum.emplace_back (prefix_f (n / i)); + if (n / i <= lim) { + id[0][n / i] = sz(quotient) - 1; + } else { + id[1][i] = sz(quotient) - 1; + } + } + EratosthenesSieve (lim, primes); + compute (); + } + +}; From 7ae7930e3f785fd3633d8b9220eb63a32c758abc Mon Sep 17 00:00:00 2001 From: xaengceilbiths <31133127+xaengceilbiths@users.noreply.github.com> Date: Tue, 1 Dec 2020 23:33:31 +0800 Subject: [PATCH 20/51] do {} while(0) --- .../Template.cpp" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" index d351ba1..3cffa82 100644 --- "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" +++ "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" @@ -83,7 +83,7 @@ void debug_out (Head H, Tail... T) { #ifdef LOCAL #define dbg(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__) #else -#define dbg(...) {} +#define dbg(...) do {} while(0) #endif template From 7a0991bfd854e57fb82e7b2c5271d52f0305a75e Mon Sep 17 00:00:00 2001 From: samzhang Date: Tue, 29 Dec 2020 00:40:58 +0800 Subject: [PATCH 21/51] Update Suffix-Automaton.cpp --- .../Suffix-Automaton.cpp" | 66 ++++++++++--------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git "a/\345\255\227\347\254\246\344\270\262/Suffix-Automaton.cpp" "b/\345\255\227\347\254\246\344\270\262/Suffix-Automaton.cpp" index ca0af2e..f58122b 100644 --- "a/\345\255\227\347\254\246\344\270\262/Suffix-Automaton.cpp" +++ "b/\345\255\227\347\254\246\344\270\262/Suffix-Automaton.cpp" @@ -1,83 +1,89 @@ struct SAM { - static const int maxn = 300010 * 2; + static const int N = 500010 * 2, ALPHABET = 2, BASE = '0'; struct Node { - Node *nxt[26], *fail; + Node *nxt[ALPHABET], *fail; int cnt; int len; }; Node *root; int cnt; - Node no[maxn]; + Node no[N]; - Node *newNode () { - memset (&no[cnt], 0, sizeof (Node)); + Node *newNode() { + memset(&no[cnt], 0, sizeof(Node)); return &no[cnt++]; } - void init () { + void init() { cnt = 0; - root = newNode (); + root = newNode(); } - SAM () { - init (); + SAM() { + init(); } - void add (const string &s) { + void add(const string &s) { Node *cur = root; - REP(i, 0, sz (s)) { - cur = add (cur, s[i] - 'a'); + REP(i, 0, sz(s)) + { + cur = add(cur, s[i]); } } - Node *add (Node *p, int c) { - Node *cur = newNode (); + Node *add(Node *p, int c) { + c -= BASE; + Node *cur = newNode(); cur->len = p->len + 1; - while (p && !p->nxt[c])p->nxt[c] = cur, p = p->fail; - if (!p) { + while(p && !p->nxt[c])p->nxt[c] = cur, p = p->fail; + if(!p) { cur->fail = root; return cur; } Node *q = p->nxt[c]; - if (q->len == p->len + 1) { + if(q->len == p->len + 1) { cur->fail = q; } else { - Node *nq = newNode (); + Node *nq = newNode(); *nq = *q; nq->len = p->len + 1; q->fail = cur->fail = nq; - while (p && p->nxt[c] == q)p->nxt[c] = nq, p = p->fail; + while(p && p->nxt[c] == q)p->nxt[c] = nq, p = p->fail; } return cur; } - void pre (const string &s) { + void pre(const string &s) { Node *cur = root; - REP(i, 0, sz (s)) { - cur = cur->nxt[s[i] - 'a']; + REP(i, 0, sz(s)) + { + cur = cur->nxt[s[i] - BASE]; cur->cnt++; } } //call pre first //return sum of cnt - void getCnt () { - vector v; - REP(i, 1, cnt) { - v.PB (&no[i]); + void getCnt() { + vector < Node * > v; + REP(i, 1, cnt) + { + v.PB(&no[i]); } - sort (all(v), [] (const Node *a, const Node *b) { + sort(all(v), [](const Node *a, const Node *b) { return a->len > b->len; }); - REP(i, 0, sz (v)) { + REP(i, 0, sz(v)) + { v[i]->fail->cnt += v[i]->cnt; } } - ll getNumOfDistinctSubstrings () { + ll getNumOfDistinctSubstrings() { ll ans = 0; - REP(i, 1, cnt)ans += no[i].len - no[i].fail->len; + REP(i, 1, cnt) + ans += no[i].len - no[i].fail->len; return (ans); } }; From 3658bfb512f60e0f4b755ee3cc204ec9849d0e7a Mon Sep 17 00:00:00 2001 From: samzhang Date: Fri, 8 Oct 2021 22:45:05 +0800 Subject: [PATCH 22/51] amend Template.cpp --- .../Template.cpp" | 92 +++++++------------ 1 file changed, 35 insertions(+), 57 deletions(-) diff --git "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" index 3cffa82..72784b6 100644 --- "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" +++ "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" @@ -1,15 +1,3 @@ -#pragma comment(linker, "/stack:200000000") -#pragma GCC optimize("Ofast") -//#pragma GCC optimize(3) -//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") -//#pragma GCC target("sse3","sse2","sse") -//#pragma GCC target("avx","sse4","sse4.1","sse4.2","ssse3") -//#pragma GCC target("f16c") -//#pragma GCC optimize("inline","fast-math","unroll-loops","no-stack-protector") -//#pragma GCC diagnostic error "-fwhole-program" -//#pragma GCC diagnostic error "-fcse-skip-blocks" -//#pragma GCC diagnostic error "-funsafe-loop-optimizations" -//#pragma GCC diagnostic error "-std=c++14" #include "bits/stdc++.h" #include "ext/pb_ds/tree_policy.hpp" #include "ext/pb_ds/assoc_container.hpp" @@ -20,8 +8,8 @@ #define UB upper_bound #define fr(x) freopen(x,"r",stdin) #define fw(x) freopen(x,"w",stdout) -#define REP(x, l, u) for(ll x = l;x=u;x--) +#define REP(i, from, to) for(ll i = from;i=to;x--) #define complete_unique(a) a.erase(unique(begin(a),end(a)),end(a)) #define mst(x, a) memset(x,a,sizeof(x)) #define all(a) begin(a),end(a) @@ -50,34 +38,34 @@ typedef vector VI; const ll mod = 1e9 + 7; -string to_string (string s) { return '"' + s + '"'; } +string to_string(string s) { return '"' + s + '"'; } -string to_string (const char *s) { return to_string ((string) s); } +string to_string(const char *s) { return to_string((string) s); } -string to_string (bool b) { return (b ? "true" : "false"); } +string to_string(bool b) { return (b ? "true" : "false"); } template -string to_string (pair p) { return "(" + to_string (p.first) + ", " + to_string (p.second) + ")"; } +string to_string(pair p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; } template -string to_string (A v) { +string to_string(A v) { bool first = true; string res = "{"; - for (const auto &x : v) { - if (!first) { res += ", "; } + for(const auto &x: v) { + if(!first) { res += ", "; } first = false; - res += to_string (x); + res += to_string(x); } res += "}"; return res; } -void debug_out () { cerr< -void debug_out (Head H, Tail... T) { - cerr<<" "< -inline bool upmin (T &a, const S &b) { return a > b ? a = b, 1 : 0; } +inline bool upmin(T &a, const S &b) { return a > b ? a = b, 1 : 0; } template -inline bool upmax (T &a, const S &b) { return a < b ? a = b, 1 : 0; } +inline bool upmax(T &a, const S &b) { return a < b ? a = b, 1 : 0; } -ull twop (ll x) { return 1ULL< -T sqr (T x) { return x * x; } +T sqr(T x) { return x * x; } -ll gcd (ll a, ll b) { - a = abs (a), b = abs (b); - while (b != 0) { - a %= b; - swap (a, b); - } - return a; -} - -ll fast (ll a, ll b, ll mod) { +ll fast(ll a, ll b, ll mod) { a %= mod; - if (b < 0)a = inverse (a, mod), b = -b; + if(b < 0)a = inverse(a, mod), b = -b; ll ans = 1; - while (b) { - if (b & 1)ans = ans * a % mod; + while(b) { + if(b & 1)ans = ans * a % mod; a = a * a % mod; b /= 2; } @@ -133,27 +112,26 @@ ll fast (ll a, ll b, ll mod) { namespace SOLVE { - void main () { + void main() { } } - -signed main () { +signed main() { #ifdef LOCAL fr("/Users/zhangqingchuan/Desktop/cp/cp/input.txt"); fw("/Users/zhangqingchuan/Desktop/cp/cp/output.txt"); #endif - ios::sync_with_stdio (false); - cin.tie (nullptr); - cout.tie (nullptr); + ios::sync_with_stdio(false); + cin.tie(nullptr); + cout.tie(nullptr); int t = 1; // cin >> t; - for (int i = 1; i <= t; i++) { + for(int i = 1; i <= t; i++) { // cout<<"Case #"< Date: Fri, 8 Oct 2021 22:47:26 +0800 Subject: [PATCH 23/51] fix error in REP --- .../Template.cpp" | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" index 72784b6..39f4fcf 100644 --- "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" +++ "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" @@ -8,8 +8,8 @@ #define UB upper_bound #define fr(x) freopen(x,"r",stdin) #define fw(x) freopen(x,"w",stdout) -#define REP(i, from, to) for(ll i = from;i=to;x--) +#define REP(i, from, to) for(ll i = from;i=to;i--) #define complete_unique(a) a.erase(unique(begin(a),end(a)),end(a)) #define mst(x, a) memset(x,a,sizeof(x)) #define all(a) begin(a),end(a) From 8eba11e32fd1a54473a2ec3bb9a50f4a8e31beba Mon Sep 17 00:00:00 2001 From: samzhang Date: Sun, 10 Oct 2021 01:09:05 +0800 Subject: [PATCH 24/51] header --- .../Template.cpp" | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" index 39f4fcf..b575ca7 100644 --- "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" +++ "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" @@ -1,6 +1,6 @@ -#include "bits/stdc++.h" -#include "ext/pb_ds/tree_policy.hpp" -#include "ext/pb_ds/assoc_container.hpp" +#include +#include +#include #define PB push_back #define PF push_front From df4942d23c5623bebd4790b1931bef369baf41ab Mon Sep 17 00:00:00 2001 From: samzhang Date: Sun, 10 Oct 2021 01:10:22 +0800 Subject: [PATCH 25/51] type safety --- .../Template.cpp" | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" index b575ca7..b4ad50b 100644 --- "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" +++ "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" @@ -14,8 +14,6 @@ #define mst(x, a) memset(x,a,sizeof(x)) #define all(a) begin(a),end(a) #define rall(a) rbegin(a),rend(a) -#define PII pair -#define PLL pair #define MP make_pair #define lowbit(x) ((x)&(-(x))) #define bitcnt(x) (__builtin_popcountll(x)) @@ -26,15 +24,18 @@ #define sz(x) ((int)x.size()) #define EX0 exit(0); -typedef long long ll; -typedef unsigned long long ull; -typedef double db; -typedef long double ld; +using ll = long long; +using ull = unsigned long long; +using db = double; +using ld = long double; +using VLL = std::vector; +using VI = std::vector; +using PII = std::pair; +using PLL = std::pair; + using namespace __gnu_pbds; //required using namespace std; template using ordered_set = tree, rb_tree_tag, tree_order_statistics_node_update>; -typedef vector VLL; -typedef vector VI; const ll mod = 1e9 + 7; @@ -98,6 +99,9 @@ ll inverse(ll a, ll m) { template T sqr(T x) { return x * x; } +template +ll sz(const T &x) { return x.size(); } + ll fast(ll a, ll b, ll mod) { a %= mod; if(b < 0)a = inverse(a, mod), b = -b; From 0d30ce07b7ae760167040f8a5ce6343e159d51a4 Mon Sep 17 00:00:00 2001 From: samzhang Date: Sun, 10 Oct 2021 01:10:39 +0800 Subject: [PATCH 26/51] type safety --- .../Template.cpp" | 1 - 1 file changed, 1 deletion(-) diff --git "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" index b4ad50b..a6e273f 100644 --- "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" +++ "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" @@ -21,7 +21,6 @@ #define rson (ind<<1|1) #define se second #define fi first -#define sz(x) ((int)x.size()) #define EX0 exit(0); using ll = long long; From 7f75bf6f64fee92cb80c1671ca7c170950e856f4 Mon Sep 17 00:00:00 2001 From: Qingchuan Zhang Date: Sun, 5 Dec 2021 14:39:59 +0800 Subject: [PATCH 27/51] fix off by one bug in euler path --- "\345\233\276\350\256\272/Euler-Path.cpp" | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git "a/\345\233\276\350\256\272/Euler-Path.cpp" "b/\345\233\276\350\256\272/Euler-Path.cpp" index cf8347a..5e74083 100644 --- "a/\345\233\276\350\256\272/Euler-Path.cpp" +++ "b/\345\233\276\350\256\272/Euler-Path.cpp" @@ -76,7 +76,7 @@ namespace EulerPath { void init (int n, const vector &edges) { - REP (i, 0, n + 1) + REP (i, 0, n) adj[i].clear (); path.clear (); for (auto e:edges) { @@ -95,6 +95,7 @@ namespace EulerPath { for (auto e:edges) { n = max (n, max (e.first, e.second)); } + n++; init (n, edges); int source = getSource (n, edges[0].first); find_path (source); From c0f3c3e056d4b3b38c13d1529f33d3f13f4caa3b Mon Sep 17 00:00:00 2001 From: Qingchuan Zhang Date: Sun, 16 Jan 2022 01:39:48 +0800 Subject: [PATCH 28/51] add platform-specific IO files --- .../Template.cpp" | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" index a6e273f..5af88d9 100644 --- "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" +++ "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" @@ -120,16 +120,23 @@ namespace SOLVE { } } +#ifdef __APPLE__ +#define INPUT_FILE "/Users/qingczha/Desktop/cp/input.txt" +#define OUTPUT_FILE "/Users/qingczha/Desktop/cp/output.txt" +#else +#define INPUT_FILE "" +#define OUTPUT_FILE "" +#endif + signed main() { #ifdef LOCAL - fr("/Users/zhangqingchuan/Desktop/cp/cp/input.txt"); - fw("/Users/zhangqingchuan/Desktop/cp/cp/output.txt"); + fr(INPUT_FILE); + fw(OUTPUT_FILE); #endif ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); - int t = 1; // cin >> t; for(int i = 1; i <= t; i++) { From ded2773ff03264b7cc900de0f28397ed659b243c Mon Sep 17 00:00:00 2001 From: Qingchuan Zhang Date: Sun, 16 Jan 2022 02:17:12 +0800 Subject: [PATCH 29/51] minor fix --- .../Template.cpp" | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" index 5af88d9..017a054 100644 --- "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" +++ "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" @@ -121,8 +121,8 @@ namespace SOLVE { } #ifdef __APPLE__ -#define INPUT_FILE "/Users/qingczha/Desktop/cp/input.txt" -#define OUTPUT_FILE "/Users/qingczha/Desktop/cp/output.txt" +#define INPUT_FILE "/Users/qingczha/ClionProjects/Playground/input.txt" +#define OUTPUT_FILE "/Users/qingczha/ClionProjects/Playground/output.txt" #else #define INPUT_FILE "" #define OUTPUT_FILE "" From 884fc5a04f0d3634537450bcbb7f42df27679626 Mon Sep 17 00:00:00 2001 From: Qingchuan Zhang Date: Sat, 2 Apr 2022 16:53:45 +0800 Subject: [PATCH 30/51] add IO file path under windows --- .../Template.cpp" | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" index 017a054..ae43d44 100644 --- "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" +++ "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" @@ -124,8 +124,8 @@ namespace SOLVE { #define INPUT_FILE "/Users/qingczha/ClionProjects/Playground/input.txt" #define OUTPUT_FILE "/Users/qingczha/ClionProjects/Playground/output.txt" #else -#define INPUT_FILE "" -#define OUTPUT_FILE "" +#define INPUT_FILE "C:/Users/qingczha/CLionProjects/playground/input.txt" +#define OUTPUT_FILE "C:/Users/qingczha/CLionProjects/playground/output.txt" #endif signed main() { From 879cd35431a6748a25f271e84122b9c36d4b6bee Mon Sep 17 00:00:00 2001 From: Qingchuan Zhang Date: Sat, 2 Apr 2022 23:04:27 +0800 Subject: [PATCH 31/51] fix template.cpp --- .../Template.cpp" | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" index ae43d44..235244d 100644 --- "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" +++ "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" @@ -121,8 +121,8 @@ namespace SOLVE { } #ifdef __APPLE__ -#define INPUT_FILE "/Users/qingczha/ClionProjects/Playground/input.txt" -#define OUTPUT_FILE "/Users/qingczha/ClionProjects/Playground/output.txt" +#define INPUT_FILE "/Users/qingczha/ClionProjects/LeetCode/input.txt" +#define OUTPUT_FILE "/Users/qingczha/ClionProjects/LeetCode/output.txt" #else #define INPUT_FILE "C:/Users/qingczha/CLionProjects/playground/input.txt" #define OUTPUT_FILE "C:/Users/qingczha/CLionProjects/playground/output.txt" From ee1201cccb571d235ee186b09de3398c3151b2c1 Mon Sep 17 00:00:00 2001 From: Qingchuan Zhang Date: Sun, 16 Oct 2022 00:12:05 +0800 Subject: [PATCH 32/51] update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8fa0fc1..cf35b50 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.pdf *.sh *.py +.idea \ No newline at end of file From 6bd1d7e6df667cc2889d635c88029ea744a9e61d Mon Sep 17 00:00:00 2001 From: Qingchuan Zhang Date: Sun, 16 Oct 2022 00:13:19 +0800 Subject: [PATCH 33/51] update .gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index cf35b50..ca2c0b9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ *.pdf *.sh *.py -.idea \ No newline at end of file +**/.idea \ No newline at end of file From 8367c7894cad642b347eb986fd7ed5857ac7d533 Mon Sep 17 00:00:00 2001 From: Qingchuan Zhang Date: Sun, 19 Feb 2023 23:07:33 +0800 Subject: [PATCH 34/51] add LeetCode.cpp --- .../LeetCode.cpp" | 186 ++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 "\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/LeetCode.cpp" diff --git "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/LeetCode.cpp" "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/LeetCode.cpp" new file mode 100644 index 0000000..8852a9d --- /dev/null +++ "b/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/LeetCode.cpp" @@ -0,0 +1,186 @@ +#include +#include +#include + +#define PB push_back +#define PF push_front +#define LB lower_bound +#define UB upper_bound +#define fr(x) freopen(x,"r",stdin) +#define fw(x) freopen(x,"w",stdout) +#define REP(i, from, to) for(ll i = from;i=to;i--) +#define complete_unique(a) a.erase(unique(begin(a),end(a)),end(a)) +#define mst(x, a) memset(x,a,sizeof(x)) +#define all(a) begin(a),end(a) +#define rall(a) rbegin(a),rend(a) +#define MP make_pair +#define lowbit(x) ((x)&(-(x))) +#define bitcnt(x) (__builtin_popcountll(x)) +#define lson (ind<<1) +#define rson (ind<<1|1) +#define se second +#define fi first +#define EX0 exit(0); + +using ll = long long; +using ull = unsigned long long; +using db = double; +using ld = long double; +using VLL = std::vector; +using VI = std::vector; +using PII = std::pair; +using PLL = std::pair; + +using namespace __gnu_pbds; //required +using namespace std; +template using ordered_set = tree, rb_tree_tag, tree_order_statistics_node_update>; +const ll mod = 1e9 + 7; + + +string to_string(string s) { return '"' + s + '"'; } + +string to_string(const char *s) { return to_string((string) s); } + +string to_string(bool b) { return (b ? "true" : "false"); } + +template +string to_string(pair p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; } + +template +string to_string(A v) { + bool first = true; + string res = "{"; + for(const auto &x: v) { + if(!first) { res += ", "; } + first = false; + res += to_string(x); + } + res += "}"; + return res; +} + +void debug_out() { cerr << endl; } + +template +void debug_out(Head H, Tail... T) { + cerr << " " << to_string(H); + debug_out(T...); +} + +#ifdef LOCAL +#define dbg(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__) +#else +#define dbg(...) do {} while(0) +#endif + +template +inline bool upmin(T &a, const S &b) { return a > b ? a = b, 1 : 0; } + +template +inline bool upmax(T &a, const S &b) { return a < b ? a = b, 1 : 0; } + + +ull twop(ll x) { return 1ULL << x; } + +ll MOD(ll a, ll m) { + a %= m; + if(a < 0)a += m; + return a; +} + +ll inverse(ll a, ll m) { + a = MOD(a, m); + if(a <= 1)return a; + return MOD((1 - inverse(m, a) * m) / a, m); +} + +template +T sqr(T x) { return x * x; } + +template +ll sz(const T &x) { return x.size(); } + +ll fast(ll a, ll b, ll mod) { + a %= mod; + if(b < 0)a = inverse(a, mod), b = -b; + ll ans = 1; + while(b) { + if(b & 1)ans = ans * a % mod; + a = a * a % mod; + b /= 2; + } + return ans % mod; +} + + + + + + + + + + + + + + + + + + + +#ifdef LOCAL + + +namespace SOLVE { + void main() { + + } +} + +#ifdef __APPLE__ +#define INPUT_FILE "/Users/qingczha/ClionProjects/LeetCode/input.txt" +#define OUTPUT_FILE "/Users/qingczha/ClionProjects/LeetCode/output.txt" +#else +#define INPUT_FILE "C:/Users/qingczha/CLionProjects/playground/input.txt" +#define OUTPUT_FILE "C:/Users/qingczha/CLionProjects/playground/output.txt" +#endif + +signed main() { + fr(INPUT_FILE); + fw(OUTPUT_FILE); + ios::sync_with_stdio(false); + cin.tie(nullptr); + cout.tie(nullptr); + + int t = 1; +// cin >> t; + for(int i = 1; i <= t; i++) { +// cout<<"Case #"< Date: Sat, 25 Feb 2023 14:16:42 +0800 Subject: [PATCH 35/51] add mod as template parameter of matrix class --- "\346\225\260\345\255\246/Matrix.cpp" | 1 + 1 file changed, 1 insertion(+) diff --git "a/\346\225\260\345\255\246/Matrix.cpp" "b/\346\225\260\345\255\246/Matrix.cpp" index cad8b77..fba146f 100644 --- "a/\346\225\260\345\255\246/Matrix.cpp" +++ "b/\346\225\260\345\255\246/Matrix.cpp" @@ -1,3 +1,4 @@ +template struct matrix { //add mod at last if there is negative number vector v; From 17614a2110dfe5db8f5e5da38ed674c6350536dd Mon Sep 17 00:00:00 2001 From: Qingchuan Zhang Date: Sat, 25 Feb 2023 14:16:56 +0800 Subject: [PATCH 36/51] minor fix --- .../Polynomial-Interpolation.cpp" | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git "a/\346\225\260\345\255\246/Polynomial-Interpolation.cpp" "b/\346\225\260\345\255\246/Polynomial-Interpolation.cpp" index cc863b7..16bda24 100644 --- "a/\346\225\260\345\255\246/Polynomial-Interpolation.cpp" +++ "b/\346\225\260\345\255\246/Polynomial-Interpolation.cpp" @@ -4,11 +4,11 @@ template std::vector interpolation(const T x[], const T y[], int n) { std::vector u(y, y + n), ret(n), sum(n); ret[0] = u[0], sum[0] = 1; - for (int i = 1; i < n; ++i) { - for (int j = n - 1; j >= i; --j) { + for(int i = 1; i < n; ++i) { + for(int j = n - 1; j >= i; --j) { u[j] = (u[j] - u[j - 1]) / (x[j] - x[j - i]); } - for (int j = i; j; --j) { + for(int j = i; j; --j) { sum[j] = -sum[j] * x[i - 1] + sum[j - 1]; ret[j] += sum[j] * u[i]; } @@ -20,13 +20,13 @@ std::vector interpolation(const T x[], const T y[], int n) { // f(x) is degree m - 1, given f(0), f(1), ..., f(m - 1), // return f(n) in linear time -ll evaluate(const std::vector &f, ll n, ll mod) { - for(auto&i:f) i = MOD(i,mod); +ll evaluate(std::vector &f, ll n, ll mod) { + for(auto &i: f) i = MOD(i, mod); ll m = f.size(), nn = n % mod; - if (n < m) return f[n]; + if(n < m) return f[n]; std::vector inv(m + 1), fact(m + 1), ifact(m + 1); inv[1] = fact[0] = ifact[0] = fact[1] = ifact[1] = 1; - for (int i = 2; i <= m; ++i) { + for(int i = 2; i <= m; ++i) { inv[i] = ll(mod - mod / i) * inv[mod % i] % mod; fact[i] = (ll) i * fact[i - 1] % mod; ifact[i] = (ll) inv[i] * ifact[i - 1] % mod; @@ -34,32 +34,32 @@ ll evaluate(const std::vector &f, ll n, ll mod) { ll ret = 0, v = 1; std::vector s(m + 1); s[m] = 1; - for (int i = m - 1; i >= 0; --i) { + for(int i = m - 1; i >= 0; --i) { v = (ll) v * (nn - i + mod) % mod; s[i] = (ll) s[i + 1] * (nn - i + mod) % mod; - if (i == nn) s[i] = 1; + if(i == nn) s[i] = 1; } - v = pow_mod(v, mod - 2, mod); - for (int i = 0; i < m; ++i) { + v = inverse(v, mod); + for(int i = 0; i < m; ++i) { ll inv2 = (ll) v * s[i + 1] % mod; v = (ll) v * (nn - i + mod) % mod; ll mul = (ll) ifact[i] * ifact[m - 1 - i] % mod * inv2 % mod; - if ((m - 1 - i) & 1) mul = mod - mul; - if (i != nn) { + if((m - 1 - i) & 1) mul = mod - mul; + if(i != nn) { ret += f[i] * mul % mod; } - if (ret >= mod) ret -= mod; + if(ret >= mod) ret -= mod; } - for (int i = 0; i < m; ++i) { + for(int i = 0; i < m; ++i) { ret = (ll) ret * (nn - i + mod) % mod; } - if (nn <= m - 1) { + if(nn <= m - 1) { ll extra = f[nn] * ifact[nn] % mod * ifact[m - 1 - nn] % mod; - if ((m - 1 - nn) & 1) extra = mod - extra; - for (int i = 0; i < m; ++i) { - if (i != nn) extra = extra * (nn - i + mod) % mod; + if((m - 1 - nn) & 1) extra = mod - extra; + for(int i = 0; i < m; ++i) { + if(i != nn) extra = extra * (nn - i + mod) % mod; } ret = (ret + extra) % mod; } - return MOD(ret,mod); + return MOD(ret, mod); } From 74aa95acc70dad559ead32d25f16c3662665bcf9 Mon Sep 17 00:00:00 2001 From: qingczha Date: Fri, 21 Jun 2024 19:59:25 +0800 Subject: [PATCH 37/51] add CMakeLists.txt to make Clion happy --- CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..3519b16 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.28) + +project(CP-Templates) + +file(GLOB_RECURSE ALL_CPP_FILES "*.cpp") + +add_library(qc_lib ${ALL_CPP_FILES}) From 6f3b1832281f031fed0821683df3f1df184139d3 Mon Sep 17 00:00:00 2001 From: qingczha Date: Fri, 21 Jun 2024 19:59:45 +0800 Subject: [PATCH 38/51] add include --- "\346\225\260\346\215\256\347\273\223\346\236\204/DSU.cpp" | 2 ++ 1 file changed, 2 insertions(+) diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/DSU.cpp" "b/\346\225\260\346\215\256\347\273\223\346\236\204/DSU.cpp" index 56a6abb..2cd5fd4 100644 --- "a/\346\225\260\346\215\256\347\273\223\346\236\204/DSU.cpp" +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/DSU.cpp" @@ -1,3 +1,5 @@ +#include + struct DSU { std::vector data; From b40c25152da5b762f43f8a169acb36abf3047fcc Mon Sep 17 00:00:00 2001 From: qingczha Date: Fri, 21 Jun 2024 20:02:20 +0800 Subject: [PATCH 39/51] fix Calendar.cpp --- "\345\205\266\344\273\226/Calendar.cpp" | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git "a/\345\205\266\344\273\226/Calendar.cpp" "b/\345\205\266\344\273\226/Calendar.cpp" index 39b1abc..bbd3246 100644 --- "a/\345\205\266\344\273\226/Calendar.cpp" +++ "b/\345\205\266\344\273\226/Calendar.cpp" @@ -1,4 +1,4 @@ -#include "bits/stdc++.h" +#include int week(int y, int m, int d) { if (m < 3) { @@ -9,11 +9,6 @@ int week(int y, int m, int d) { return w; } -int main() { - printf("%d\n", week(2015, 4, 16)); // => 3 Thursday - printf("%d\n", week(1989, 2, 3)); // => 4 Friday - return 0; -} bool isLeap(int year) { return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0); @@ -26,3 +21,8 @@ int getDays(int year, int month) { } +int main() { + std::printf("%d\n", week(2015, 4, 16)); // => 3 Thursday + std::printf("%d\n", week(1989, 2, 3)); // => 4 Friday + return 0; +} From debbbfba514dffe380dbadf9783ea48dcab606e6 Mon Sep 17 00:00:00 2001 From: qingczha Date: Fri, 21 Jun 2024 20:03:57 +0800 Subject: [PATCH 40/51] fix n-queen special solution.cpp --- .../n-queen special solution.cpp" | 48 ++++++++----------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git "a/\345\205\266\344\273\226/n-queen special solution.cpp" "b/\345\205\266\344\273\226/n-queen special solution.cpp" index 9868b4b..27ffd5f 100644 --- "a/\345\205\266\344\273\226/n-queen special solution.cpp" +++ "b/\345\205\266\344\273\226/n-queen special solution.cpp" @@ -1,34 +1,28 @@ -#include -int main() -{ +#include + +int main() { int n; - scanf("%d",&n); - if(n == 2 || n == 3){ + std::cin >> n; + if (n == 2 || n == 3) { printf("-1"); return 0; } - if (n%6!=2&&n%6!=3) - { - for(int i=2;i<=n;i+=2)printf("%d ",i-1); - for(int i=1;i<=n;i+=2)printf("%d ",i-1); - } - else - { - int k=n>>1; - if (k&1) - { - for(int i=k;i<=n-1;i+=2)printf("%d ",i-1); - for(int i=1;i<=k-1;i+=2)printf("%d ",i-1); - for(int i=k+3;i<=n;i+=2)printf("%d ",i-1); - for(int i=2;i<=k+1;i+=2)printf("%d ",i-1); - } - else - { - for(int i=k;i<=n;i+=2)printf("%d ",i-1); - for(int i=2;i<=k-1;i+=2)printf("%d ",i-1);; - for(int i=k+3;i<=n-1;i+=2)printf("%d ",i-1); - for(int i=1;i<=k+1;i+=2)printf("%d ",i-1); + if (n % 6 != 2 && n % 6 != 3) { + for (int i = 2; i <= n; i += 2)printf("%d ", i - 1); + for (int i = 1; i <= n; i += 2)printf("%d ", i - 1); + } else { + int k = n >> 1; + if (k & 1) { + for (int i = k; i <= n - 1; i += 2)printf("%d ", i - 1); + for (int i = 1; i <= k - 1; i += 2)printf("%d ", i - 1); + for (int i = k + 3; i <= n; i += 2)printf("%d ", i - 1); + for (int i = 2; i <= k + 1; i += 2)printf("%d ", i - 1); + } else { + for (int i = k; i <= n; i += 2)printf("%d ", i - 1); + for (int i = 2; i <= k - 1; i += 2)printf("%d ", i - 1);; + for (int i = k + 3; i <= n - 1; i += 2)printf("%d ", i - 1); + for (int i = 1; i <= k + 1; i += 2)printf("%d ", i - 1); } - if (n&1)printf("%d ",n-1);; + if (n & 1)printf("%d ", n - 1);; } } From 5086e4e01b2e5895729abde31f8d44252c92275e Mon Sep 17 00:00:00 2001 From: qingczha Date: Fri, 21 Jun 2024 20:08:34 +0800 Subject: [PATCH 41/51] fix Geometry.cpp --- "\345\207\240\344\275\225/Geometry.cpp" | 184 ++++++++++++------------ 1 file changed, 94 insertions(+), 90 deletions(-) diff --git "a/\345\207\240\344\275\225/Geometry.cpp" "b/\345\207\240\344\275\225/Geometry.cpp" index 455aba0..3c885d2 100644 --- "a/\345\207\240\344\275\225/Geometry.cpp" +++ "b/\345\207\240\344\275\225/Geometry.cpp" @@ -1,165 +1,169 @@ +#include +#include +#include + using flt = double; using int64 = long long; -const flt eps = 1e-8, pi = acos (-1.0); +const flt eps = 1e-8, pi = std::acos(-1.0); template -inline int sgn (T x, T e = eps) { return x < -e ? -1 : x > e; } +inline int sgn(T x, T e = eps) { return x < -e ? -1 : x > e; } template -inline T cmp (T a, T b, T e = eps) { - return std::abs (a - b) >= e + std::abs (a) * e ? a - b : 0; +inline T cmp(T a, T b, T e = eps) { + return std::abs(a - b) >= e + std::abs(a) * e ? a - b : 0; } -inline flt fix (flt x, flt e = eps) { return cmp (x, flt (0), e); } +inline flt fix(flt x, flt e = eps) { return cmp(x, flt(0), e); } template struct Point { T x, y; - - Point (T x = 0, T y = 0) : x (x), y (y) {} - - bool operator< (const Point &o) const { return x < o.x || (x == o.x && y < o.y); } - - bool operator== (const Point &o) const { return x == o.x && y == o.y; } - - Point operator+ (const Point &o) const { return Point (x + o.x, y + o.y); } - - Point operator- (const Point &o) const { return Point (x - o.x, y - o.y); } - - Point operator* (T k) const { return Point (x * k, y * k); } - - Point operator/ (T k) const { return Point (x / k, y / k); } - - T dot (const Point &o) const { return x * o.x + y * o.y; } - - T det (const Point &o) const { return x * o.y - y * o.x; } - - T norm2 () const { return x * x + y * y; } - - flt norm () const { return hypot (x, y); } - - flt ang () const { return atan2 (y, x); } - - Point perp () const { return Point (-y, x); } // rotate 90 degrees - Point unit () const { return *this / norm (); } - - Point trunc (flt k) const { return unit () * k; } - - // counter clockwise rotate a rad - Point rot (flt a) const { - return Point (x * cos (a) - y * sin (a), x * sin (a) + y * cos (a)); + + explicit Point(T x = 0, T y = 0) : x(x), y(y) {} + + bool operator<(const Point &o) const { return x < o.x || (x == o.x && y < o.y); } + + bool operator==(const Point &o) const { return x == o.x && y == o.y; } + + Point operator+(const Point &o) const { return Point(x + o.x, y + o.y); } + + Point operator-(const Point &o) const { return Point(x - o.x, y - o.y); } + + Point operator*(T k) const { return Point(x * k, y * k); } + + Point operator/(T k) const { return Point(x / k, y / k); } + + [[nodiscard]] T dot(const Point &o) const { return x * o.x + y * o.y; } + + [[nodiscard]] T det(const Point &o) const { return x * o.y - y * o.x; } + + [[nodiscard]] T norm2() const { return x * x + y * y; } + + [[nodiscard]] flt norm() const { return hypot(x, y); } + + [[nodiscard]] flt ang() const { return atan2(y, x); } + + [[nodiscard]] Point perp() const { return Point(-y, x); } // rotate 90 degrees + [[nodiscard]] Point unit() const { return *this / norm(); } + + [[nodiscard]] Point trunc(flt k) const { return unit() * k; } + + // counter-clockwise rotate a rad + [[nodiscard]] Point rot(flt a) const { + return Point(x * cos(a) - y * sin(a), x * sin(a) + y * cos(a)); } - - // counter clockwise rotate using cos/sin - Point rot (flt cosa, flt sina) const { - return Point (x * cosa - y * sina, x * sina + y * cosa); + + // counter-clockwise rotate using cos/sin + [[nodiscard]] Point rot(flt cosa, flt sina) const { + return Point(x * cosa - y * sina, x * sina + y * cosa); } - - friend ostream &operator<< (ostream &out, const Point &p) { - out<<"("< &p) { + out << "(" << p.x << "," << p.y << ")"; return out; } - + }; using point = Point; using poly_t = std::vector; template -bool on_seg (const P &a, const P &b, const P &o) { - return sgn ((a - o).det (b - o)) == 0 && sgn ((a - o).dot (b - o)) <= 0; +bool on_seg(const P &a, const P &b, const P &o) { + return sgn((a - o).det(b - o)) == 0 && sgn((a - o).dot(b - o)) <= 0; } template -bool is_parallel (const P &a, const P &b, const P &c, const P &d) { - return sgn ((b - a).det (d - c)) == 0; +bool is_parallel(const P &a, const P &b, const P &c, const P &d) { + return sgn((b - a).det(d - c)) == 0; } // find intersection of segments ab and cd, stored in p template -bool seg_inter (const P &a, const P &b, const P &c, const P &d, P &p) { - if (on_seg (a, b, c)) return p = c, true; - if (on_seg (a, b, d)) return p = d, true; - if (on_seg (c, d, a)) return p = a, true; - if (on_seg (c, d, b)) return p = b, true; +bool seg_inter(const P &a, const P &b, const P &c, const P &d, P &p) { + if (on_seg(a, b, c)) return p = c, true; + if (on_seg(a, b, d)) return p = d, true; + if (on_seg(c, d, a)) return p = a, true; + if (on_seg(c, d, b)) return p = b, true; P ab{b - a}, cd{d - c}; - if (sgn (ab.det (cd)) == 0) return false; // parallel - int d1 = sgn (ab.det (c - a)) * sgn (ab.det (d - a)); - int d2 = sgn (cd.det (a - c)) * sgn (cd.det (b - c)); - p = a + ab * (cd.det (c - a) / cd.det (ab)); + if (sgn(ab.det(cd)) == 0) return false; // parallel + int d1 = sgn(ab.det(c - a)) * sgn(ab.det(d - a)); + int d2 = sgn(cd.det(a - c)) * sgn(cd.det(b - c)); + p = a + ab * (cd.det(c - a) / cd.det(ab)); return d1 < 0 && d2 < 0; } // find intersection of lines ab and cd, stored in p template -bool line_inter (const P &a, const P &b, const P &c, const P &d, P &p) { +bool line_inter(const P &a, const P &b, const P &c, const P &d, P &p) { P ab{b - a}, cd{d - c}; - if (sgn (ab.det (cd)) == 0) return false; // parallel - p = a + ab * (cd.det (c - a) / cd.det (ab)); + if (sgn(ab.det(cd)) == 0) return false; // parallel + p = a + ab * (cd.det(c - a) / cd.det(ab)); return true; } // minimum distance from o to segment ab template -flt dis2seg (const P &a, const P &b, const P &o) { +flt dis2seg(const P &a, const P &b, const P &o) { P ao{o - a}, bo{o - b}, ab{b - a}; - if (sgn (ao.dot (ab)) < 0) return ao.norm (); - if (sgn (-bo.dot (ab)) < 0) return bo.norm (); - return std::abs (ao.det (ab)) / ab.norm (); + if (sgn(ao.dot(ab)) < 0) return ao.norm(); + if (sgn(-bo.dot(ab)) < 0) return bo.norm(); + return std::abs(ao.det(ab)) / ab.norm(); } // find the minimum distance from segment ab to segment cd template -flt dis_seg2seg (const P &a, const P &b, const P &c, const P &d) { +flt dis_seg2seg(const P &a, const P &b, const P &c, const P &d) { P o; - if (seg_inter (a, b, c, d, o)) return 0; + if (seg_inter(a, b, c, d, o)) return 0; else - return std::min (std::min (dis2seg (a, b, c), dis2seg (a, b, d)), - std::min (dis2seg (c, d, a), dis2seg (c, d, b))); + return std::min(std::min(dis2seg(a, b, c), dis2seg(a, b, d)), + std::min(dis2seg(c, d, a), dis2seg(c, d, b))); } // move line AB along normal vector -void move_d (point &a, point &b, const flt len) { - auto d = (b - a).perp ().trunc (len); +void move_d(point &a, point &b, const flt len) { + auto d = (b - a).perp().trunc(len); a = a + d, b = b + d; } // project point o on line ab -point project (const point &a, const point &b, const point &o) { +point project(const point &a, const point &b, const point &o) { auto ab = b - a; - return a + ab * (ab.dot (o - a) / ab.norm2 ()); + return a + ab * (ab.dot(o - a) / ab.norm2()); } // find the reflect point of o with respect to line ab -point reflect (const point &a, const point &b, const point &o) { +point reflect(const point &a, const point &b, const point &o) { auto ab = b - a; - return (a + ab * (ab.dot (o - a) / ab.norm2 ())) * 2 - o; + return (a + ab * (ab.dot(o - a) / ab.norm2())) * 2 - o; } /************************************ Circle Utilities *****************************************/ // check if two circles intersect, intersection will store in P and Q -bool intersect (const point &A, flt ra, const point &B, flt rb, point &P, point &Q) { - point AB (B - A); - double dis = AB.norm (); - if (sgn (dis) == 0 || sgn (dis - (ra + rb)) > 0 || sgn (dis - fabs (ra - rb)) < 0) return false; +bool intersect(const point &A, flt ra, const point &B, flt rb, point &P, point &Q) { + point AB(B - A); + double dis = AB.norm(); + if (sgn(dis) == 0 || sgn(dis - (ra + rb)) > 0 || sgn(dis - fabs(ra - rb)) < 0) return false; flt cosa = (dis * dis + ra * ra - rb * rb) / (2 * dis * ra); - flt sina = sqrt (fix (1.0 - cosa * cosa)); + flt sina = sqrt(fix(1.0 - cosa * cosa)); AB = AB * (ra / dis); - P = AB.rot (cosa, +sina) + A; - Q = AB.rot (cosa, -sina) + A; + P = AB.rot(cosa, +sina) + A; + Q = AB.rot(cosa, -sina) + A; return true; } // check if line AB intesect circle O, intersection will store in P and Q -bool intersect (const point &A, const point &B, const point &O, flt r, point &P, point &Q) { - point AB (B - A), AO (O - A); - flt dis = fabs (AB.det (AO)) / AB.norm (); - if (sgn (dis - r) > 0) return false; - point M = A + AB * (AB.dot (AO) / AB.norm2 ()); - dis = sqrt (fix (r * r - dis * dis)); - AB = AB / AB.norm () * dis; +bool intersect(const point &A, const point &B, const point &O, flt r, point &P, point &Q) { + point AB(B - A), AO(O - A); + flt dis = fabs(AB.det(AO)) / AB.norm(); + if (sgn(dis - r) > 0) return false; + point M = A + AB * (AB.dot(AO) / AB.norm2()); + dis = sqrt(fix(r * r - dis * dis)); + AB = AB / AB.norm() * dis; P = M + AB, Q = M - AB; return true; } From 4839566cd1ed52c16c2a31a50e32668b375bb6fe Mon Sep 17 00:00:00 2001 From: qingczha Date: Fri, 21 Jun 2024 20:13:22 +0800 Subject: [PATCH 42/51] overhaul --- .../Dynamic-Convex-Hull.cpp | 0 .../DSU.cpp" => DataStructure/DSU.cpp | 0 .../Fenwick-Tree.cpp | 0 .../PBDS.cpp" => DataStructure/PBDS.cpp | 0 .../Persistent-Segtree.cpp | 0 .../Segment-Tree.cpp | 0 .../Sparse-Table.cpp | 0 .../Geometry.cpp" => Geometry/Geometry.cpp | 0 .../2-Sat.cpp" => Graph/2-Sat.cpp | 0 .../BipolarOrientation.cpp | 0 .../Centroid-Decomposition.cpp | 0 .../Chordal-Graph.cpp | 0 .../Dinic.cpp" => Graph/Dinic.cpp | 0 .../Dominator-Tree.cpp | 0 .../Edmonds-Blossom.cpp | 0 .../Euler-Path.cpp" => Graph/Euler-Path.cpp | 0 .../Graph-Center.cpp | 0 .../Heavy-Light-Decomposition.cpp | 0 .../Hungarian.cpp" => Graph/Hungarian.cpp | 0 .../KM.cpp" => Graph/KM.cpp | 0 .../Kirchoff-Matrix-Tree.cpp | 0 .../LCA.cpp" => Graph/LCA.cpp | 0 .../Max-Clique.cpp" => Graph/Max-Clique.cpp | 0 .../Min-Cost-Flow.cpp | 0 .../Mininum-Arborescence.cpp | 0 .../StoerWagner.cpp" => Graph/StoerWagner.cpp | 0 .../Tarjan BCC.cpp" => Graph/Tarjan BCC.cpp | 0 .../Tarjan SCC.cpp" => Graph/Tarjan SCC.cpp | 0 ...1\345\234\206\346\226\271\346\240\221.cpp" | 90 +++++++++++++++++++ .../Basic-Maths.cpp" => Maths/Basic-Maths.cpp | 0 .../BerlekampMassey.cpp | 0 .../Binomial-Coefficient.cpp | 0 .../Congruence-Equation.cpp | 0 .../Discrete-Log.cpp | 0 .../ExGCD.cpp" => Maths/ExGCD.cpp | 0 .../FWT.cpp" => Maths/FWT.cpp | 0 .../Fast-Fourier-Transform.cpp | 0 .../Fraction.cpp" => Maths/Fraction.cpp | 0 .../Gaussian-Elimination.cpp | 0 .../Lattice-Counting.cpp | 0 .../Matrix.cpp" => Maths/Matrix.cpp | 0 .../Mod-Int.cpp" => Maths/Mod-Int.cpp | 0 .../Pollard-Rho&MillerRabin.cpp | 0 .../Polynomial-Interpolation.cpp | 0 .../Polynomial.cpp" => Maths/Polynomial.cpp | 0 .../PrimeCounting.cpp | 0 .../Sieve.cpp" => Maths/Sieve.cpp | 0 .../Simplex.cpp" => Maths/Simplex.cpp | 0 .../Xor-Basis.cpp" => Maths/Xor-Basis.cpp | 0 .../BigInt.cpp" => Misc/BigInt.cpp | 0 .../Bit-Hacks.cpp" => Misc/Bit-Hacks.cpp | 0 .../Calendar.cpp" => Misc/Calendar.cpp | 0 .../n-queen special solution.cpp | 0 ...351\224\231\350\257\257.md" => Pitfalls.md | 0 .../LeetCode.cpp" => Starter/LeetCode.cpp | 0 .../Template.cpp" => Starter/Template.cpp | 0 .../Aho-Corasick.cpp | 0 .../Dictionary-of-Basic-Factors.cpp | 0 .../EERTREE.cpp" => String/EERTREE.cpp | 0 .../KMP.cpp" => String/KMP.cpp | 0 .../Manacher.cpp" => String/Manacher.cpp | 0 .../Max-Suffix.cpp" => String/Max-Suffix.cpp | 0 .../String-Hash.cpp | 0 .../Suffix-Array.cpp | 0 .../Suffix-Automaton.cpp | 0 ...1\345\234\206\346\226\271\346\240\221.cpp" | 80 ----------------- 66 files changed, 90 insertions(+), 80 deletions(-) rename "\345\212\250\346\200\201\350\247\204\345\210\222/Dynamic-Convex-Hull.cpp" => DP/Dynamic-Convex-Hull.cpp (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204/DSU.cpp" => DataStructure/DSU.cpp (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204/Fenwick-Tree.cpp" => DataStructure/Fenwick-Tree.cpp (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204/PBDS.cpp" => DataStructure/PBDS.cpp (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204/Persistent-Segtree.cpp" => DataStructure/Persistent-Segtree.cpp (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204/Segment-Tree.cpp" => DataStructure/Segment-Tree.cpp (100%) rename "\346\225\260\346\215\256\347\273\223\346\236\204/Sparse-Table.cpp" => DataStructure/Sparse-Table.cpp (100%) rename "\345\207\240\344\275\225/Geometry.cpp" => Geometry/Geometry.cpp (100%) rename "\345\233\276\350\256\272/2-Sat.cpp" => Graph/2-Sat.cpp (100%) rename "\345\233\276\350\256\272/BipolarOrientation.cpp" => Graph/BipolarOrientation.cpp (100%) rename "\345\233\276\350\256\272/Centroid-Decomposition.cpp" => Graph/Centroid-Decomposition.cpp (100%) rename "\345\233\276\350\256\272/Chordal-Graph.cpp" => Graph/Chordal-Graph.cpp (100%) rename "\345\233\276\350\256\272/Dinic.cpp" => Graph/Dinic.cpp (100%) rename "\345\233\276\350\256\272/Dominator-Tree.cpp" => Graph/Dominator-Tree.cpp (100%) rename "\345\233\276\350\256\272/Edmonds-Blossom.cpp" => Graph/Edmonds-Blossom.cpp (100%) rename "\345\233\276\350\256\272/Euler-Path.cpp" => Graph/Euler-Path.cpp (100%) rename "\345\233\276\350\256\272/Graph-Center.cpp" => Graph/Graph-Center.cpp (100%) rename "\345\233\276\350\256\272/Heavy-Light-Decomposition.cpp" => Graph/Heavy-Light-Decomposition.cpp (100%) rename "\345\233\276\350\256\272/Hungarian.cpp" => Graph/Hungarian.cpp (100%) rename "\345\233\276\350\256\272/KM.cpp" => Graph/KM.cpp (100%) rename "\345\233\276\350\256\272/Kirchoff-Matrix-Tree.cpp" => Graph/Kirchoff-Matrix-Tree.cpp (100%) rename "\345\233\276\350\256\272/LCA.cpp" => Graph/LCA.cpp (100%) rename "\345\233\276\350\256\272/Max-Clique.cpp" => Graph/Max-Clique.cpp (100%) rename "\345\233\276\350\256\272/Min-Cost-Flow.cpp" => Graph/Min-Cost-Flow.cpp (100%) rename "\345\233\276\350\256\272/Mininum-Arborescence.cpp" => Graph/Mininum-Arborescence.cpp (100%) rename "\345\233\276\350\256\272/StoerWagner.cpp" => Graph/StoerWagner.cpp (100%) rename "\345\233\276\350\256\272/Tarjan BCC.cpp" => Graph/Tarjan BCC.cpp (100%) rename "\345\233\276\350\256\272/Tarjan SCC.cpp" => Graph/Tarjan SCC.cpp (100%) create mode 100644 "Graph/\345\271\277\344\271\211\345\234\206\346\226\271\346\240\221.cpp" rename "\346\225\260\345\255\246/Basic-Maths.cpp" => Maths/Basic-Maths.cpp (100%) rename "\346\225\260\345\255\246/BerlekampMassey.cpp" => Maths/BerlekampMassey.cpp (100%) rename "\346\225\260\345\255\246/Binomial-Coefficient.cpp" => Maths/Binomial-Coefficient.cpp (100%) rename "\346\225\260\345\255\246/Congruence-Equation.cpp" => Maths/Congruence-Equation.cpp (100%) rename "\346\225\260\345\255\246/Discrete-Log.cpp" => Maths/Discrete-Log.cpp (100%) rename "\346\225\260\345\255\246/ExGCD.cpp" => Maths/ExGCD.cpp (100%) rename "\346\225\260\345\255\246/FWT.cpp" => Maths/FWT.cpp (100%) rename "\346\225\260\345\255\246/Fast-Fourier-Transform.cpp" => Maths/Fast-Fourier-Transform.cpp (100%) rename "\346\225\260\345\255\246/Fraction.cpp" => Maths/Fraction.cpp (100%) rename "\346\225\260\345\255\246/Gaussian-Elimination.cpp" => Maths/Gaussian-Elimination.cpp (100%) rename "\346\225\260\345\255\246/Lattice-Counting.cpp" => Maths/Lattice-Counting.cpp (100%) rename "\346\225\260\345\255\246/Matrix.cpp" => Maths/Matrix.cpp (100%) rename "\346\225\260\345\255\246/Mod-Int.cpp" => Maths/Mod-Int.cpp (100%) rename "\346\225\260\345\255\246/Pollard-Rho&MillerRabin.cpp" => Maths/Pollard-Rho&MillerRabin.cpp (100%) rename "\346\225\260\345\255\246/Polynomial-Interpolation.cpp" => Maths/Polynomial-Interpolation.cpp (100%) rename "\346\225\260\345\255\246/Polynomial.cpp" => Maths/Polynomial.cpp (100%) rename "\346\225\260\345\255\246/PrimeCounting.cpp" => Maths/PrimeCounting.cpp (100%) rename "\346\225\260\345\255\246/Sieve.cpp" => Maths/Sieve.cpp (100%) rename "\346\225\260\345\255\246/Simplex.cpp" => Maths/Simplex.cpp (100%) rename "\346\225\260\345\255\246/Xor-Basis.cpp" => Maths/Xor-Basis.cpp (100%) rename "\345\205\266\344\273\226/BigInt.cpp" => Misc/BigInt.cpp (100%) rename "\345\205\266\344\273\226/Bit-Hacks.cpp" => Misc/Bit-Hacks.cpp (100%) rename "\345\205\266\344\273\226/Calendar.cpp" => Misc/Calendar.cpp (100%) rename "\345\205\266\344\273\226/n-queen special solution.cpp" => Misc/n-queen special solution.cpp (100%) rename "\345\270\270\350\247\201\351\224\231\350\257\257.md" => Pitfalls.md (100%) rename "\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/LeetCode.cpp" => Starter/LeetCode.cpp (100%) rename "\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" => Starter/Template.cpp (100%) rename "\345\255\227\347\254\246\344\270\262/Aho-Corasick.cpp" => String/Aho-Corasick.cpp (100%) rename "\345\255\227\347\254\246\344\270\262/Dictionary-of-Basic-Factors.cpp" => String/Dictionary-of-Basic-Factors.cpp (100%) rename "\345\255\227\347\254\246\344\270\262/EERTREE.cpp" => String/EERTREE.cpp (100%) rename "\345\255\227\347\254\246\344\270\262/KMP.cpp" => String/KMP.cpp (100%) rename "\345\255\227\347\254\246\344\270\262/Manacher.cpp" => String/Manacher.cpp (100%) rename "\345\255\227\347\254\246\344\270\262/Max-Suffix.cpp" => String/Max-Suffix.cpp (100%) rename "\345\255\227\347\254\246\344\270\262/String-Hash.cpp" => String/String-Hash.cpp (100%) rename "\345\255\227\347\254\246\344\270\262/Suffix-Array.cpp" => String/Suffix-Array.cpp (100%) rename "\345\255\227\347\254\246\344\270\262/Suffix-Automaton.cpp" => String/Suffix-Automaton.cpp (100%) delete mode 100644 "\345\233\276\350\256\272/\345\271\277\344\271\211\345\234\206\346\226\271\346\240\221.cpp" diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/Dynamic-Convex-Hull.cpp" b/DP/Dynamic-Convex-Hull.cpp similarity index 100% rename from "\345\212\250\346\200\201\350\247\204\345\210\222/Dynamic-Convex-Hull.cpp" rename to DP/Dynamic-Convex-Hull.cpp diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/DSU.cpp" b/DataStructure/DSU.cpp similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204/DSU.cpp" rename to DataStructure/DSU.cpp diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/Fenwick-Tree.cpp" b/DataStructure/Fenwick-Tree.cpp similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204/Fenwick-Tree.cpp" rename to DataStructure/Fenwick-Tree.cpp diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/PBDS.cpp" b/DataStructure/PBDS.cpp similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204/PBDS.cpp" rename to DataStructure/PBDS.cpp diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/Persistent-Segtree.cpp" b/DataStructure/Persistent-Segtree.cpp similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204/Persistent-Segtree.cpp" rename to DataStructure/Persistent-Segtree.cpp diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/Segment-Tree.cpp" b/DataStructure/Segment-Tree.cpp similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204/Segment-Tree.cpp" rename to DataStructure/Segment-Tree.cpp diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/Sparse-Table.cpp" b/DataStructure/Sparse-Table.cpp similarity index 100% rename from "\346\225\260\346\215\256\347\273\223\346\236\204/Sparse-Table.cpp" rename to DataStructure/Sparse-Table.cpp diff --git "a/\345\207\240\344\275\225/Geometry.cpp" b/Geometry/Geometry.cpp similarity index 100% rename from "\345\207\240\344\275\225/Geometry.cpp" rename to Geometry/Geometry.cpp diff --git "a/\345\233\276\350\256\272/2-Sat.cpp" b/Graph/2-Sat.cpp similarity index 100% rename from "\345\233\276\350\256\272/2-Sat.cpp" rename to Graph/2-Sat.cpp diff --git "a/\345\233\276\350\256\272/BipolarOrientation.cpp" b/Graph/BipolarOrientation.cpp similarity index 100% rename from "\345\233\276\350\256\272/BipolarOrientation.cpp" rename to Graph/BipolarOrientation.cpp diff --git "a/\345\233\276\350\256\272/Centroid-Decomposition.cpp" b/Graph/Centroid-Decomposition.cpp similarity index 100% rename from "\345\233\276\350\256\272/Centroid-Decomposition.cpp" rename to Graph/Centroid-Decomposition.cpp diff --git "a/\345\233\276\350\256\272/Chordal-Graph.cpp" b/Graph/Chordal-Graph.cpp similarity index 100% rename from "\345\233\276\350\256\272/Chordal-Graph.cpp" rename to Graph/Chordal-Graph.cpp diff --git "a/\345\233\276\350\256\272/Dinic.cpp" b/Graph/Dinic.cpp similarity index 100% rename from "\345\233\276\350\256\272/Dinic.cpp" rename to Graph/Dinic.cpp diff --git "a/\345\233\276\350\256\272/Dominator-Tree.cpp" b/Graph/Dominator-Tree.cpp similarity index 100% rename from "\345\233\276\350\256\272/Dominator-Tree.cpp" rename to Graph/Dominator-Tree.cpp diff --git "a/\345\233\276\350\256\272/Edmonds-Blossom.cpp" b/Graph/Edmonds-Blossom.cpp similarity index 100% rename from "\345\233\276\350\256\272/Edmonds-Blossom.cpp" rename to Graph/Edmonds-Blossom.cpp diff --git "a/\345\233\276\350\256\272/Euler-Path.cpp" b/Graph/Euler-Path.cpp similarity index 100% rename from "\345\233\276\350\256\272/Euler-Path.cpp" rename to Graph/Euler-Path.cpp diff --git "a/\345\233\276\350\256\272/Graph-Center.cpp" b/Graph/Graph-Center.cpp similarity index 100% rename from "\345\233\276\350\256\272/Graph-Center.cpp" rename to Graph/Graph-Center.cpp diff --git "a/\345\233\276\350\256\272/Heavy-Light-Decomposition.cpp" b/Graph/Heavy-Light-Decomposition.cpp similarity index 100% rename from "\345\233\276\350\256\272/Heavy-Light-Decomposition.cpp" rename to Graph/Heavy-Light-Decomposition.cpp diff --git "a/\345\233\276\350\256\272/Hungarian.cpp" b/Graph/Hungarian.cpp similarity index 100% rename from "\345\233\276\350\256\272/Hungarian.cpp" rename to Graph/Hungarian.cpp diff --git "a/\345\233\276\350\256\272/KM.cpp" b/Graph/KM.cpp similarity index 100% rename from "\345\233\276\350\256\272/KM.cpp" rename to Graph/KM.cpp diff --git "a/\345\233\276\350\256\272/Kirchoff-Matrix-Tree.cpp" b/Graph/Kirchoff-Matrix-Tree.cpp similarity index 100% rename from "\345\233\276\350\256\272/Kirchoff-Matrix-Tree.cpp" rename to Graph/Kirchoff-Matrix-Tree.cpp diff --git "a/\345\233\276\350\256\272/LCA.cpp" b/Graph/LCA.cpp similarity index 100% rename from "\345\233\276\350\256\272/LCA.cpp" rename to Graph/LCA.cpp diff --git "a/\345\233\276\350\256\272/Max-Clique.cpp" b/Graph/Max-Clique.cpp similarity index 100% rename from "\345\233\276\350\256\272/Max-Clique.cpp" rename to Graph/Max-Clique.cpp diff --git "a/\345\233\276\350\256\272/Min-Cost-Flow.cpp" b/Graph/Min-Cost-Flow.cpp similarity index 100% rename from "\345\233\276\350\256\272/Min-Cost-Flow.cpp" rename to Graph/Min-Cost-Flow.cpp diff --git "a/\345\233\276\350\256\272/Mininum-Arborescence.cpp" b/Graph/Mininum-Arborescence.cpp similarity index 100% rename from "\345\233\276\350\256\272/Mininum-Arborescence.cpp" rename to Graph/Mininum-Arborescence.cpp diff --git "a/\345\233\276\350\256\272/StoerWagner.cpp" b/Graph/StoerWagner.cpp similarity index 100% rename from "\345\233\276\350\256\272/StoerWagner.cpp" rename to Graph/StoerWagner.cpp diff --git "a/\345\233\276\350\256\272/Tarjan BCC.cpp" b/Graph/Tarjan BCC.cpp similarity index 100% rename from "\345\233\276\350\256\272/Tarjan BCC.cpp" rename to Graph/Tarjan BCC.cpp diff --git "a/\345\233\276\350\256\272/Tarjan SCC.cpp" b/Graph/Tarjan SCC.cpp similarity index 100% rename from "\345\233\276\350\256\272/Tarjan SCC.cpp" rename to Graph/Tarjan SCC.cpp diff --git "a/Graph/\345\271\277\344\271\211\345\234\206\346\226\271\346\240\221.cpp" "b/Graph/\345\271\277\344\271\211\345\234\206\346\226\271\346\240\221.cpp" new file mode 100644 index 0000000..25ab93e --- /dev/null +++ "b/Graph/\345\271\277\344\271\211\345\234\206\346\226\271\346\240\221.cpp" @@ -0,0 +1,90 @@ +#include + + +namespace CircleSquareTree { + using ll = long long; + using VLL = std::vector; + + struct Edge { + ll from, to, id; + + Edge(ll from, ll to, ll id) : from(from), to(to), id(id) {} + }; + + + const ll N = 500010 * 2; //开两倍 + + ll low[N], dfn[N], cnt = 1, square; + std::vector adj[N]; + std::vector stack; + + VLL realAdj[N]; // 点双树边 + + void addRealEdge(int a, int b) { + realAdj[a].push_back(b); + realAdj[b].push_back(a); + } + + void addEdge(int a, int b, int id) { + adj[a].emplace_back(a, b, id); + adj[b].emplace_back(b, a, id); + } + + void tarjan(ll cur, Edge edge) { + dfn[cur] = low[cur] = cnt++; + for (auto e: adj[cur]) { + if (e.id != edge.id) { + auto to = e.to; + if (!dfn[to]) { + stack.push_back(e); + tarjan(to, e); + upmin(low[cur], low[to]); + if (low[to] >= dfn[cur]) { + std::vector components; + while (true) { + auto cur = stack.back(); + stack.pop_back(); + components.push_back(cur); + if (cur.id == e.id)break; + } + if (components.size() == 1) { + // bridge + addRealEdge(cur, e.to); + } else { + // bcc + auto center = square++; + for (auto edge: components) { + addRealEdge(center, edge.from); + addRealEdge(center, edge.to); + } + } + } + } else { + upmin(low[cur], dfn[to]); + } + } + } + } + + // 圆方树在realAdj,编号为 [1,square) + void run(int n, std::vector edges) { + fill(low, low + n + 1, 0); + fill(dfn, dfn + n + 1, 0); + cnt = 1, square = n + 1; + REP(i, 0, (n + 1) * 2) + adj[i].clear(); + REP(i, 0, (n + 1) * 2) + realAdj[i].clear(); + stack.clear(); + REP(i, 0, sz(edges)) + { + addEdge(edges[i].fi, edges[i].se, i); + } + tarjan(1, Edge(0, 0, -1)); + REP(i, 1, square) + { + sort(all(realAdj[i])); + complete_unique(realAdj[i]); + } + } +} diff --git "a/\346\225\260\345\255\246/Basic-Maths.cpp" b/Maths/Basic-Maths.cpp similarity index 100% rename from "\346\225\260\345\255\246/Basic-Maths.cpp" rename to Maths/Basic-Maths.cpp diff --git "a/\346\225\260\345\255\246/BerlekampMassey.cpp" b/Maths/BerlekampMassey.cpp similarity index 100% rename from "\346\225\260\345\255\246/BerlekampMassey.cpp" rename to Maths/BerlekampMassey.cpp diff --git "a/\346\225\260\345\255\246/Binomial-Coefficient.cpp" b/Maths/Binomial-Coefficient.cpp similarity index 100% rename from "\346\225\260\345\255\246/Binomial-Coefficient.cpp" rename to Maths/Binomial-Coefficient.cpp diff --git "a/\346\225\260\345\255\246/Congruence-Equation.cpp" b/Maths/Congruence-Equation.cpp similarity index 100% rename from "\346\225\260\345\255\246/Congruence-Equation.cpp" rename to Maths/Congruence-Equation.cpp diff --git "a/\346\225\260\345\255\246/Discrete-Log.cpp" b/Maths/Discrete-Log.cpp similarity index 100% rename from "\346\225\260\345\255\246/Discrete-Log.cpp" rename to Maths/Discrete-Log.cpp diff --git "a/\346\225\260\345\255\246/ExGCD.cpp" b/Maths/ExGCD.cpp similarity index 100% rename from "\346\225\260\345\255\246/ExGCD.cpp" rename to Maths/ExGCD.cpp diff --git "a/\346\225\260\345\255\246/FWT.cpp" b/Maths/FWT.cpp similarity index 100% rename from "\346\225\260\345\255\246/FWT.cpp" rename to Maths/FWT.cpp diff --git "a/\346\225\260\345\255\246/Fast-Fourier-Transform.cpp" b/Maths/Fast-Fourier-Transform.cpp similarity index 100% rename from "\346\225\260\345\255\246/Fast-Fourier-Transform.cpp" rename to Maths/Fast-Fourier-Transform.cpp diff --git "a/\346\225\260\345\255\246/Fraction.cpp" b/Maths/Fraction.cpp similarity index 100% rename from "\346\225\260\345\255\246/Fraction.cpp" rename to Maths/Fraction.cpp diff --git "a/\346\225\260\345\255\246/Gaussian-Elimination.cpp" b/Maths/Gaussian-Elimination.cpp similarity index 100% rename from "\346\225\260\345\255\246/Gaussian-Elimination.cpp" rename to Maths/Gaussian-Elimination.cpp diff --git "a/\346\225\260\345\255\246/Lattice-Counting.cpp" b/Maths/Lattice-Counting.cpp similarity index 100% rename from "\346\225\260\345\255\246/Lattice-Counting.cpp" rename to Maths/Lattice-Counting.cpp diff --git "a/\346\225\260\345\255\246/Matrix.cpp" b/Maths/Matrix.cpp similarity index 100% rename from "\346\225\260\345\255\246/Matrix.cpp" rename to Maths/Matrix.cpp diff --git "a/\346\225\260\345\255\246/Mod-Int.cpp" b/Maths/Mod-Int.cpp similarity index 100% rename from "\346\225\260\345\255\246/Mod-Int.cpp" rename to Maths/Mod-Int.cpp diff --git "a/\346\225\260\345\255\246/Pollard-Rho&MillerRabin.cpp" b/Maths/Pollard-Rho&MillerRabin.cpp similarity index 100% rename from "\346\225\260\345\255\246/Pollard-Rho&MillerRabin.cpp" rename to Maths/Pollard-Rho&MillerRabin.cpp diff --git "a/\346\225\260\345\255\246/Polynomial-Interpolation.cpp" b/Maths/Polynomial-Interpolation.cpp similarity index 100% rename from "\346\225\260\345\255\246/Polynomial-Interpolation.cpp" rename to Maths/Polynomial-Interpolation.cpp diff --git "a/\346\225\260\345\255\246/Polynomial.cpp" b/Maths/Polynomial.cpp similarity index 100% rename from "\346\225\260\345\255\246/Polynomial.cpp" rename to Maths/Polynomial.cpp diff --git "a/\346\225\260\345\255\246/PrimeCounting.cpp" b/Maths/PrimeCounting.cpp similarity index 100% rename from "\346\225\260\345\255\246/PrimeCounting.cpp" rename to Maths/PrimeCounting.cpp diff --git "a/\346\225\260\345\255\246/Sieve.cpp" b/Maths/Sieve.cpp similarity index 100% rename from "\346\225\260\345\255\246/Sieve.cpp" rename to Maths/Sieve.cpp diff --git "a/\346\225\260\345\255\246/Simplex.cpp" b/Maths/Simplex.cpp similarity index 100% rename from "\346\225\260\345\255\246/Simplex.cpp" rename to Maths/Simplex.cpp diff --git "a/\346\225\260\345\255\246/Xor-Basis.cpp" b/Maths/Xor-Basis.cpp similarity index 100% rename from "\346\225\260\345\255\246/Xor-Basis.cpp" rename to Maths/Xor-Basis.cpp diff --git "a/\345\205\266\344\273\226/BigInt.cpp" b/Misc/BigInt.cpp similarity index 100% rename from "\345\205\266\344\273\226/BigInt.cpp" rename to Misc/BigInt.cpp diff --git "a/\345\205\266\344\273\226/Bit-Hacks.cpp" b/Misc/Bit-Hacks.cpp similarity index 100% rename from "\345\205\266\344\273\226/Bit-Hacks.cpp" rename to Misc/Bit-Hacks.cpp diff --git "a/\345\205\266\344\273\226/Calendar.cpp" b/Misc/Calendar.cpp similarity index 100% rename from "\345\205\266\344\273\226/Calendar.cpp" rename to Misc/Calendar.cpp diff --git "a/\345\205\266\344\273\226/n-queen special solution.cpp" b/Misc/n-queen special solution.cpp similarity index 100% rename from "\345\205\266\344\273\226/n-queen special solution.cpp" rename to Misc/n-queen special solution.cpp diff --git "a/\345\270\270\350\247\201\351\224\231\350\257\257.md" b/Pitfalls.md similarity index 100% rename from "\345\270\270\350\247\201\351\224\231\350\257\257.md" rename to Pitfalls.md diff --git "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/LeetCode.cpp" b/Starter/LeetCode.cpp similarity index 100% rename from "\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/LeetCode.cpp" rename to Starter/LeetCode.cpp diff --git "a/\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" b/Starter/Template.cpp similarity index 100% rename from "\345\244\264\346\226\207\344\273\266\345\217\212\346\265\213\350\257\225/Template.cpp" rename to Starter/Template.cpp diff --git "a/\345\255\227\347\254\246\344\270\262/Aho-Corasick.cpp" b/String/Aho-Corasick.cpp similarity index 100% rename from "\345\255\227\347\254\246\344\270\262/Aho-Corasick.cpp" rename to String/Aho-Corasick.cpp diff --git "a/\345\255\227\347\254\246\344\270\262/Dictionary-of-Basic-Factors.cpp" b/String/Dictionary-of-Basic-Factors.cpp similarity index 100% rename from "\345\255\227\347\254\246\344\270\262/Dictionary-of-Basic-Factors.cpp" rename to String/Dictionary-of-Basic-Factors.cpp diff --git "a/\345\255\227\347\254\246\344\270\262/EERTREE.cpp" b/String/EERTREE.cpp similarity index 100% rename from "\345\255\227\347\254\246\344\270\262/EERTREE.cpp" rename to String/EERTREE.cpp diff --git "a/\345\255\227\347\254\246\344\270\262/KMP.cpp" b/String/KMP.cpp similarity index 100% rename from "\345\255\227\347\254\246\344\270\262/KMP.cpp" rename to String/KMP.cpp diff --git "a/\345\255\227\347\254\246\344\270\262/Manacher.cpp" b/String/Manacher.cpp similarity index 100% rename from "\345\255\227\347\254\246\344\270\262/Manacher.cpp" rename to String/Manacher.cpp diff --git "a/\345\255\227\347\254\246\344\270\262/Max-Suffix.cpp" b/String/Max-Suffix.cpp similarity index 100% rename from "\345\255\227\347\254\246\344\270\262/Max-Suffix.cpp" rename to String/Max-Suffix.cpp diff --git "a/\345\255\227\347\254\246\344\270\262/String-Hash.cpp" b/String/String-Hash.cpp similarity index 100% rename from "\345\255\227\347\254\246\344\270\262/String-Hash.cpp" rename to String/String-Hash.cpp diff --git "a/\345\255\227\347\254\246\344\270\262/Suffix-Array.cpp" b/String/Suffix-Array.cpp similarity index 100% rename from "\345\255\227\347\254\246\344\270\262/Suffix-Array.cpp" rename to String/Suffix-Array.cpp diff --git "a/\345\255\227\347\254\246\344\270\262/Suffix-Automaton.cpp" b/String/Suffix-Automaton.cpp similarity index 100% rename from "\345\255\227\347\254\246\344\270\262/Suffix-Automaton.cpp" rename to String/Suffix-Automaton.cpp diff --git "a/\345\233\276\350\256\272/\345\271\277\344\271\211\345\234\206\346\226\271\346\240\221.cpp" "b/\345\233\276\350\256\272/\345\271\277\344\271\211\345\234\206\346\226\271\346\240\221.cpp" deleted file mode 100644 index 8751b05..0000000 --- "a/\345\233\276\350\256\272/\345\271\277\344\271\211\345\234\206\346\226\271\346\240\221.cpp" +++ /dev/null @@ -1,80 +0,0 @@ -namespace CircleSquareTree { - struct Edge { - ll from, to, id; - - Edge (ll from, ll to, ll id) : from (from), to (to), id (id) {} - }; - - - const ll N = 500010*2; //开两倍 - - ll low[N], dfn[N], cnt = 1, square; - vector adj[N]; - vector stack; - - VLL realAdj[N]; // 点双树边 - - void addRealEdge (int a, int b) { - realAdj[a].PB (b); - realAdj[b].PB (a); - } - - void addEdge (int a, int b, int id) { - adj[a].PB (Edge (a, b, id)); - adj[b].PB (Edge (b, a, id)); - } - - void tarjan (ll cur, Edge edge) { - dfn[cur] = low[cur] = cnt++; - for (auto e:adj[cur]) { - if (e.id != edge.id) { - auto to = e.to; - if (!dfn[to]) { - stack.PB (e); - tarjan (to, e); - upmin (low[cur], low[to]); - if (low[to] >= dfn[cur]) { - vector components; - while (true) { - auto cur = stack.back (); - stack.pop_back (); - components.PB (cur); - if (cur.id == e.id)break; - } - if (sz(components) == 1) { - // bridge - addRealEdge (cur, e.to); - } else { - // bcc - auto center = square++; - for (auto edge:components) { - addRealEdge (center, edge.from); - addRealEdge (center, edge.to); - } - } - } - } else { - upmin (low[cur], dfn[to]); - } - } - } - } - - // 圆方树在realAdj,编号为 [1,square) - void run (int n, vector edges) { - fill (low, low + n + 1, 0); - fill (dfn, dfn + n + 1, 0); - cnt = 1, square = n + 1; - REP(i, 0, (n + 1) * 2)adj[i].clear (); - REP(i, 0, (n + 1) * 2)realAdj[i].clear (); - stack.clear (); - REP(i, 0, sz (edges)) { - addEdge (edges[i].fi, edges[i].se, i); - } - tarjan (1, Edge (0, 0, -1)); - REP(i, 1, square) { - sort (all(realAdj[i])); - complete_unique(realAdj[i]); - } - } -} From 031be7307a73632f3d9021aee7cbd2d954be2267 Mon Sep 17 00:00:00 2001 From: qingczha Date: Fri, 21 Jun 2024 20:39:29 +0800 Subject: [PATCH 43/51] add linux support --- Starter/LeetCode.cpp | 5 ++++- Starter/Template.cpp | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Starter/LeetCode.cpp b/Starter/LeetCode.cpp index 8852a9d..e070dba 100644 --- a/Starter/LeetCode.cpp +++ b/Starter/LeetCode.cpp @@ -143,9 +143,12 @@ namespace SOLVE { #ifdef __APPLE__ #define INPUT_FILE "/Users/qingczha/ClionProjects/LeetCode/input.txt" #define OUTPUT_FILE "/Users/qingczha/ClionProjects/LeetCode/output.txt" -#else +#elifdef _WIN64 #define INPUT_FILE "C:/Users/qingczha/CLionProjects/playground/input.txt" #define OUTPUT_FILE "C:/Users/qingczha/CLionProjects/playground/output.txt" +#elifdef __linux__ +#define INPUT_FILE "/home/qingczha/proj/Playground/input.txt" +#define OUTPUT_FILE "/home/qingczha/proj/Playground/output.txt" #endif signed main() { diff --git a/Starter/Template.cpp b/Starter/Template.cpp index 235244d..8b9caee 100644 --- a/Starter/Template.cpp +++ b/Starter/Template.cpp @@ -123,9 +123,12 @@ namespace SOLVE { #ifdef __APPLE__ #define INPUT_FILE "/Users/qingczha/ClionProjects/LeetCode/input.txt" #define OUTPUT_FILE "/Users/qingczha/ClionProjects/LeetCode/output.txt" -#else +#elifdef _WIN64 #define INPUT_FILE "C:/Users/qingczha/CLionProjects/playground/input.txt" #define OUTPUT_FILE "C:/Users/qingczha/CLionProjects/playground/output.txt" +#elifdef __linux__ +#define INPUT_FILE "/home/qingczha/proj/Playground/input.txt" +#define OUTPUT_FILE "/home/qingczha/proj/Playground/output.txt" #endif signed main() { From aaf666ba6f54979df28d8b2abc6cdd84fc5f3bf6 Mon Sep 17 00:00:00 2001 From: qingczha Date: Sun, 14 Jul 2024 10:28:01 +0800 Subject: [PATCH 44/51] beautify --- String/KMP.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/String/KMP.cpp b/String/KMP.cpp index 9c22b9c..dcbc650 100644 --- a/String/KMP.cpp +++ b/String/KMP.cpp @@ -1,6 +1,10 @@ -void calcNext(const string &s, int nxt[]) { +#include +#include +#include + +void calcNext(const std::string &s, int nxt[]) { int p = nxt[0] = -1; - REP(i, 1, sz(s)){ + for (int i = 1; i < s.size(); i++) { while (p != -1 && s[p + 1] != s[i])p = nxt[p]; p += s[p + 1] == s[i]; nxt[i] = p; @@ -8,13 +12,13 @@ void calcNext(const string &s, int nxt[]) { } -vector exkmp(const string &s) { +std::vector exkmp(const std::string &s) { int n = s.size(); - vector z(n); + std::vector z(n); int x = 0, y = 0; - for(int i = 1; i < n; i++) { - z[i] = max(0, min(z[i - x], y - i + 1)); - while(i + z[i] < n && s[z[i]] == s[i + z[i]]) { + for (int i = 1; i < n; i++) { + z[i] = std::max(0, std::min(z[i - x], y - i + 1)); + while (i + z[i] < n && s[z[i]] == s[i + z[i]]) { x = i; y = i + z[i]; z[i]++; From 680826757b9d6c1e851c1036db35bbfc3bd83f96 Mon Sep 17 00:00:00 2001 From: qingczha Date: Tue, 10 Sep 2024 17:52:23 +0800 Subject: [PATCH 45/51] fix --- Maths/FWT.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Maths/FWT.cpp b/Maths/FWT.cpp index 0199eee..171cd1a 100644 --- a/Maths/FWT.cpp +++ b/Maths/FWT.cpp @@ -9,7 +9,7 @@ void FWT(int a[], int n) { //or:a[i+j+d]=x+y; } } -1 + void UFWT(int a[], int n) { for (int d = 1; d < n; d <<= 1) //你甚至可以RANDOMSHUFFLE for (int m = d << 1, i = 0; i < n; i += m) From 25f17c8e118b4c475d1f0a839f2d1520e30c2d84 Mon Sep 17 00:00:00 2001 From: qingczha Date: Sun, 29 Sep 2024 23:54:39 +0800 Subject: [PATCH 46/51] fix x y position --- DataStructure/DSU.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/DataStructure/DSU.cpp b/DataStructure/DSU.cpp index 2cd5fd4..f7a2d57 100644 --- a/DataStructure/DSU.cpp +++ b/DataStructure/DSU.cpp @@ -2,10 +2,10 @@ struct DSU { std::vector data; - + void init(int n) { data.assign(n, -1); } - bool merge(int y, int x) { + bool merge(int x, int y) { x = root(x); y = root(y); if (x != y) { @@ -15,9 +15,9 @@ struct DSU { } return x != y; } - + bool same(int x, int y) { return root(x) == root(y); } - + int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); } int size(int x) { return -data[root(x)]; } @@ -28,25 +28,25 @@ namespace DSU2 { const static int MAXN = 100000 + 10; int fa[MAXN], ds[MAXN], rk[MAXN]; int S[MAXN], top; - + void init(int n) { for (int i = 1; i <= n; ++i) { fa[i] = i, rk[i] = ds[i] = 0; } top = 0; } - + int dis(int x) { int r(0); for (; x != fa[x]; x = fa[x]) r ^= ds[x]; return r; } - + int get(int x) { while (x != fa[x]) x = fa[x]; return fa[x]; } - + void merge(int x, int y, int d) { x = get(x); y = get(y); @@ -57,7 +57,7 @@ namespace DSU2 { ds[x] = d; S[++top] = x; } - + void restore(int ed) { for (; top > ed; --top) { if (S[top] < 0) --rk[-S[top]]; From bc080370b72300ab14805b27ffb7a283c01b6ecd Mon Sep 17 00:00:00 2001 From: qingczha Date: Sat, 5 Oct 2024 08:21:43 +0800 Subject: [PATCH 47/51] double has to be declared as constexpr --- Graph/KM.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Graph/KM.cpp b/Graph/KM.cpp index 3de9584..391d019 100644 --- a/Graph/KM.cpp +++ b/Graph/KM.cpp @@ -4,7 +4,7 @@ struct KM { typedef long long cost_t; static const int N = 1000; - static const cost_t inf = 1e9; + static constexpr cost_t inf = 1e9; cost_t lx[N], ly[N], sl[N]; int px[N], py[N], sy[N], fa[N], n; From fe6d762821eaa2ec9d7dddff63fed7f8f4ccaf47 Mon Sep 17 00:00:00 2001 From: qingczha Date: Sat, 5 Oct 2024 12:01:01 +0800 Subject: [PATCH 48/51] =?UTF-8?q?=E7=94=A8oi-wiki=E7=9A=84=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=EF=BC=8C=E5=8E=9F=E6=9D=A5=E7=9A=84=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E4=B8=8D=E7=9F=A5=E9=81=93=E5=93=AA=E9=87=8C=E6=9C=89=E7=82=B9?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Graph/Hungarian.cpp | 149 +++++++++++++++++++++++++++++++++----------- 1 file changed, 111 insertions(+), 38 deletions(-) diff --git a/Graph/Hungarian.cpp b/Graph/Hungarian.cpp index d3ea20d..6e886a9 100644 --- a/Graph/Hungarian.cpp +++ b/Graph/Hungarian.cpp @@ -1,46 +1,119 @@ -struct Hungarian { - std::vector vc, is;// vertex corver and independent set - std::vector pos, neg;// pos为左侧点所匹配到的右侧点编号, neg反之 - std::vector vis, mark;// 分别记录左右点的访问情况 - // 左侧点数目n, 右侧点数目m, 以及左边点到右边点的边表 - // 返回最大匹配数目, 方案存在pos和neg里面 - // vc和is记录了最小点覆盖和最大独立集的方案 - int run(int n, int m, std::vector edges[]) { - neg.assign(m, -1), pos.assign(n, -1); - mark.resize(m), vis.resize(n); - int ret = 0; - for (int i = 0; i < n; ++i) { - std::fill(mark.begin(), mark.end(), false); - std::fill(vis.begin(), vis.end(), false); - if (aug(i, edges)) ++ret; +#include + +using namespace std; + +template +struct hungarian { // km + int n; + vector matchx; + vector matchy; + vector pre; + vector visx; + vector visy; + vector lx; + vector ly; + vector > g; + vector slack; + T inf; + T res; + queue q; + + hungarian(int _n, int _m) { + n = max(_n, _m); + inf = numeric_limits::max(); + res = 0; + g = vector >(n, vector(n)); + matchx = vector(n, -1); + matchy = vector(n, -1); + pre = vector(n); + visx = vector(n); + visy = vector(n); + lx = vector(n, -inf); + ly = vector(n); + slack = vector(n); + } + + void addEdge(int u, int v, T w) { + assert(w >= 0); + g[u][v] = w; + } + + bool check(int v) { + visy[v] = true; + if (matchy[v] != -1) { + q.push(matchy[v]); + visx[matchy[v]] = true; + return false; } - std::fill(mark.begin(), mark.end(), false); - std::fill(vis.begin(), vis.end(), false); - for (int i = 0; i < n; ++i) { - if (pos[i] == -1) aug(i, edges); + while (v != -1) { + matchy[v] = pre[v]; + swap(v, matchx[pre[v]]); } - vc.clear(), is.clear(); - for (int i = 0; i < n; ++i) { - if (!vis[i]) vc.push_back(i); - else is.push_back(i); + return true; + } + + void bfs(int i) { + while (!q.empty()) { + q.pop(); } - for (int i = 0; i < m; ++i) { - if (mark[i]) vc.push_back(i); - else is.push_back(i); + q.push(i); + visx[i] = true; + while (true) { + while (!q.empty()) { + int u = q.front(); + q.pop(); + for (int v = 0; v < n; v++) { + if (!visy[v]) { + T delta = lx[u] + ly[v] - g[u][v]; + if (slack[v] >= delta) { + pre[v] = u; + if (delta) { + slack[v] = delta; + } else if (check(v)) { + return; + } + } + } + } + } + // 没有增广路 修改顶标 + T a = inf; + for (int j = 0; j < n; j++) { + if (!visy[j]) { + a = min(a, slack[j]); + } + } + for (int j = 0; j < n; j++) { + if (visx[j]) { // S + lx[j] -= a; + } + if (visy[j]) { // T + ly[j] += a; + } else { // T' + slack[j] -= a; + } + } + for (int j = 0; j < n; j++) { + if (!visy[j] && slack[j] == 0 && check(j)) { + return; + } + } } - return ret; } - - bool aug(int u, std::vector edges[]) { - vis[u] = true; - for (auto &&v: edges[u]) - if (!mark[v]) { - mark[v] = true; - if (neg[v] == -1 || aug(neg[v], edges)) { - pos[u] = v, neg[v] = u; - return true; - } + + void solve() { + // 初始顶标 + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + lx[i] = max(lx[i], g[i][j]); } - return false; + } + + for (int i = 0; i < n; i++) { + fill(slack.begin(), slack.end(), inf); + fill(visx.begin(), visx.end(), false); + fill(visy.begin(), visy.end(), false); + bfs(i); + } } }; From a276f8280523418da4385619d3111ed04e5392ed Mon Sep 17 00:00:00 2001 From: qingczha Date: Wed, 9 Oct 2024 22:35:40 +0800 Subject: [PATCH 49/51] minor --- Starter/LeetCode.cpp | 60 ++++++++++++++++---------------------------- Starter/Template.cpp | 43 ++++++++++++++++--------------- 2 files changed, 42 insertions(+), 61 deletions(-) diff --git a/Starter/LeetCode.cpp b/Starter/LeetCode.cpp index e070dba..67a3f47 100644 --- a/Starter/LeetCode.cpp +++ b/Starter/LeetCode.cpp @@ -21,7 +21,6 @@ #define rson (ind<<1|1) #define se second #define fi first -#define EX0 exit(0); using ll = long long; using ull = unsigned long long; @@ -51,8 +50,8 @@ template string to_string(A v) { bool first = true; string res = "{"; - for(const auto &x: v) { - if(!first) { res += ", "; } + for (const auto &x: v) { + if (!first) { res += ", "; } first = false; res += to_string(x); } @@ -74,24 +73,24 @@ void debug_out(Head H, Tail... T) { #define dbg(...) do {} while(0) #endif -template -inline bool upmin(T &a, const S &b) { return a > b ? a = b, 1 : 0; } +template +void setmin(T &a, U b) { if (b < a) a = b; } -template -inline bool upmax(T &a, const S &b) { return a < b ? a = b, 1 : 0; } +template +void setmax(T &a, U b) { if (b > a) a = b; } ull twop(ll x) { return 1ULL << x; } ll MOD(ll a, ll m) { a %= m; - if(a < 0)a += m; + if (a < 0)a += m; return a; } ll inverse(ll a, ll m) { a = MOD(a, m); - if(a <= 1)return a; + if (a <= 1)return a; return MOD((1 - inverse(m, a) * m) / a, m); } @@ -103,10 +102,10 @@ ll sz(const T &x) { return x.size(); } ll fast(ll a, ll b, ll mod) { a %= mod; - if(b < 0)a = inverse(a, mod), b = -b; + if (b < 0)a = inverse(a, mod), b = -b; ll ans = 1; - while(b) { - if(b & 1)ans = ans * a % mod; + while (b) { + if (b & 1)ans = ans * a % mod; a = a * a % mod; b /= 2; } @@ -114,29 +113,12 @@ ll fast(ll a, ll b, ll mod) { } - - - - - - - - - - - - - - - - - #ifdef LOCAL namespace SOLVE { void main() { - + } } @@ -157,13 +139,13 @@ signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); - + int t = 1; // cin >> t; - for(int i = 1; i <= t; i++) { + for (int i = 1; i <= t; i++) { // cout<<"Case #"< string to_string(A v) { bool first = true; string res = "{"; - for(const auto &x: v) { - if(!first) { res += ", "; } + for (const auto &x: v) { + if (!first) { res += ", "; } first = false; res += to_string(x); } @@ -74,24 +73,24 @@ void debug_out(Head H, Tail... T) { #define dbg(...) do {} while(0) #endif -template -inline bool upmin(T &a, const S &b) { return a > b ? a = b, 1 : 0; } +template +void setmin(T &a, U b) { if (b < a) a = b; } -template -inline bool upmax(T &a, const S &b) { return a < b ? a = b, 1 : 0; } +template +void setmax(T &a, U b) { if (b > a) a = b; } ull twop(ll x) { return 1ULL << x; } ll MOD(ll a, ll m) { a %= m; - if(a < 0)a += m; + if (a < 0)a += m; return a; } ll inverse(ll a, ll m) { a = MOD(a, m); - if(a <= 1)return a; + if (a <= 1)return a; return MOD((1 - inverse(m, a) * m) / a, m); } @@ -103,10 +102,10 @@ ll sz(const T &x) { return x.size(); } ll fast(ll a, ll b, ll mod) { a %= mod; - if(b < 0)a = inverse(a, mod), b = -b; + if (b < 0)a = inverse(a, mod), b = -b; ll ans = 1; - while(b) { - if(b & 1)ans = ans * a % mod; + while (b) { + if (b & 1)ans = ans * a % mod; a = a * a % mod; b /= 2; } @@ -116,7 +115,7 @@ ll fast(ll a, ll b, ll mod) { namespace SOLVE { void main() { - + } } @@ -139,13 +138,13 @@ signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); - + int t = 1; // cin >> t; - for(int i = 1; i <= t; i++) { + for (int i = 1; i <= t; i++) { // cout<<"Case #"< Date: Mon, 14 Oct 2024 23:02:12 +0800 Subject: [PATCH 50/51] minor --- Maths/Fast-Fourier-Transform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Maths/Fast-Fourier-Transform.cpp b/Maths/Fast-Fourier-Transform.cpp index 13f1fa1..516b196 100644 --- a/Maths/Fast-Fourier-Transform.cpp +++ b/Maths/Fast-Fourier-Transform.cpp @@ -38,7 +38,7 @@ namespace fft { } }; - const long double pi = M_PI; + const long double pi = std::numbers::pi; Complex w[N]; int rev[N]; From eba7bc8cb6bbf61273ebb2e3ea371358ee6b88bc Mon Sep 17 00:00:00 2001 From: qingczha Date: Sat, 26 Oct 2024 00:42:32 +0800 Subject: [PATCH 51/51] move lson/rson to segtree --- DataStructure/Segment-Tree.cpp | 3 +++ Starter/LeetCode.cpp | 2 -- Starter/Template.cpp | 2 -- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/DataStructure/Segment-Tree.cpp b/DataStructure/Segment-Tree.cpp index d537e65..1c3668c 100644 --- a/DataStructure/Segment-Tree.cpp +++ b/DataStructure/Segment-Tree.cpp @@ -1,4 +1,7 @@ struct SegTree { +#define lson (ind<<1) +#define rson (ind<<1|1) + static const int maxn =; struct node { diff --git a/Starter/LeetCode.cpp b/Starter/LeetCode.cpp index 67a3f47..4261c37 100644 --- a/Starter/LeetCode.cpp +++ b/Starter/LeetCode.cpp @@ -17,8 +17,6 @@ #define MP make_pair #define lowbit(x) ((x)&(-(x))) #define bitcnt(x) (__builtin_popcountll(x)) -#define lson (ind<<1) -#define rson (ind<<1|1) #define se second #define fi first diff --git a/Starter/Template.cpp b/Starter/Template.cpp index 6bd65b3..30482d8 100644 --- a/Starter/Template.cpp +++ b/Starter/Template.cpp @@ -17,8 +17,6 @@ #define MP make_pair #define lowbit(x) ((x)&(-(x))) #define bitcnt(x) (__builtin_popcountll(x)) -#define lson (ind<<1) -#define rson (ind<<1|1) #define se second #define fi first