ACM模板库

ACM模板库


例题

<p><img src="https://www.showdoc.com.cn/server/api/attachment/visitfile/sign/d699e1a69fe1a5bd973dd1286758e84b" alt="" /> <img src="https://www.showdoc.com.cn/server/api/attachment/visitfile/sign/ba296afb336fe490d8e9c496285cf6a4" alt="" /></p> <pre><code class="language-cpp">#include &lt;bits/stdc++.h&gt; #define RG register typedef long long LL; int Read() { int x = 0; bool f = false; char c = getchar(); while (c &lt; '0' || c &gt; '9') f |= c == '-', c = getchar(); while (c &gt;= '0' &amp;&amp; c &lt;= '9') x = (x * 10) + (c ^ 48), c = getchar(); return f ? -x : x; } template &lt;const int _MOD&gt; struct ModNumber { // 为了效率 (事实上还是不高) 省去了一些实用性 int x; inline ModNumber() { x = 0; } inline ModNumber(const int &amp;y) { x = y; } // 需保证 y 的范围! (如果在这 % _MOD 会 T, 因为代码中大量调用该构造函数) // (当然, 开 O2 可以起飞) inline int Int() { return x; } inline ModNumber Pow(LL y) const { RG int ret = 1, tmp = x; while (y) { if (y &amp; 1) ret = ((LL)ret * tmp) % _MOD; y &gt;&gt;= 1; tmp = ((LL)tmp * tmp) % _MOD; } return ModNumber(ret); } inline bool operator == (const ModNumber &amp;y) const { return x == y.x; } inline bool operator != (const ModNumber &amp;y) const { return x != y.x; } inline bool operator &lt; (const ModNumber &amp;y) const { return x &lt; y.x; } inline bool operator &gt; (const ModNumber &amp;y) const { return x &gt; y.x; } inline bool operator &lt;= (const ModNumber &amp;y) const { return x &lt;= y.x; } inline bool operator &gt;= (const ModNumber &amp;y) const { return x &gt;= y.x; } inline ModNumber operator + (const ModNumber &amp;y) const { return (x + y.x &gt;= _MOD) ? (x + y.x - _MOD) : (x + y.x); } inline ModNumber operator - (const ModNumber &amp;y) const { return (x - y.x &lt; 0) ? (x - y.x + _MOD) : (x - y.x); } inline ModNumber operator * (const ModNumber &amp;y) const { return ModNumber((LL)x * y.x % _MOD); } inline ModNumber operator / (const ModNumber &amp;y) const { return *this * y.Pow(_MOD - 2); } inline ModNumber operator ^ (const LL &amp;y) const { return Pow(y); } inline void operator += (const ModNumber &amp;y) { *this = *this + y; } inline void operator *= (const ModNumber &amp;y) { *this = *this * y; } inline void operator -= (const ModNumber &amp;y) { *this = *this - y; } inline void operator /= (const ModNumber &amp;y) { *this = *this / y; } inline void operator ^= (const LL &amp;y) const { *this = *this ^ y; } }; const int MAXN = 130000 * 4; // 所有 MAXN 都要开 4 倍! const int MOD = 1004535809; typedef ModNumber&lt;MOD&gt; Int; const Int __G = 3, One = 1, Two = 2, InvTwo = One / Two; namespace Polynomial { // 好氧, 好氧, 好氧! (无氧原地去世) // 所有 n: 多项式的项数 (即次数 + 1) // 数组从 0 开始存 int Rev[MAXN + 5]; Int G0[2][MAXN + 5]; void GetG0(const int &amp;n) { // 使用前必须先初始化 G0 for (RG int i = 2; i &lt;= n; i &lt;&lt;= 1) { G0[0][i] = __G ^ ((MOD - 1) / i); G0[1][i] = G0[0][i] ^ (MOD - 2); } } inline void GetRev(const int n) { // Rev 在函数内初始化 for (RG int i = 0; i &lt; n; i++) Rev[i] = (Rev[i &gt;&gt; 1] &gt;&gt; 1) | ((i &amp; 1) * (n &gt;&gt; 1)); } inline int ToPow(const int &amp;n) { // lim 在函数内初始化 RG int ret = 1; while (ret &lt; n) ret &lt;&lt;= 1; return ret; } void PrintPoly(Int *A, const int &amp;n) { for (RG int i = 0; i &lt; n; i++) printf("%d ", A[i].x); puts(""); } void ReadPoly(Int *A, const int &amp;n) { for (RG int i = 0; i &lt; n; i++) A[i].x = Read(); } void NTT(Int *A, const int &amp;n, const int &amp;opt) { for (RG int i = 0; i &lt; n; i++) if (i &lt; Rev[i]) std::swap(A[i], A[Rev[i]]); for (RG int mid = 1; mid &lt; n; mid &lt;&lt;= 1) { const int k = mid &lt;&lt; 1; const Int g0 = G0[opt][k]; for (RG int i = 0; i &lt; n; i += k) { Int g = 1; for (RG int j = 0; j &lt; mid; j++, g *= g0) { Int tmp1 = A[i + j], tmp2 = A[i + j + mid] * g; A[i + j] = tmp1 + tmp2, A[i + j + mid] = tmp1 - tmp2; } } } if (opt == 1) { const Int inv = One / n; for (RG int i = 0; i &lt; n; i++) A[i] *= inv; } } Int A0[MAXN + 5], B0[MAXN + 5]; void Multiply(const Int *A, const Int *B, Int *P, const int &amp;n, const int &amp;m) { // P = A * B int lim = ToPow(n + m - 1); GetRev(lim); for (int i = 0; i &lt; lim; i++) A0[i] = B0[i] = 0; for (RG int i = 0; i &lt; n; i++) A0[i] = A[i]; for (RG int i = 0; i &lt; m; i++) B0[i] = B[i]; NTT(A0, lim, 0), NTT(B0, lim, 0); for (RG int i = 0; i &lt; lim; i++) P[i] = A0[i] * B0[i]; NTT(P, lim, 1); } Int A1[MAXN + 5], B1[MAXN + 5], C1[MAXN + 5]; void Inverse(const Int *A, Int *B, const int &amp;n) { // B = 1 / A, A 不变 if (n == 1) { B[0] = A[0] ^ (MOD - 2); return; } Inverse(A, B, (n + 1) &gt;&gt; 1); const int lim = ToPow(n + n - 1); GetRev(lim); for (RG int i = 0; i &lt; n; i++) A1[i] = A[i], B1[i] = B[i]; for (RG int i = n; i &lt; lim; i++) A1[i] = B1[i] = 0; NTT(A1, lim, 0), NTT(B1, lim, 0); for (RG int i = 0; i &lt; lim; i++) C1[i] = A1[i] * B1[i] * B1[i]; NTT(C1, lim, 1); for (RG int i = 0; i &lt; n; i++) B[i] = Two * B[i] - C1[i]; for (RG int i = n; i &lt; lim; i++) B[i] = 0; } Int C2[MAXN + 5], InvB[MAXN + 5], B2[MAXN + 5]; void Sqrt(const Int *A, Int *B, const int &amp;n) { // B = √A, A 不变 (默认开根的多项式常数项为 1) if (n == 1) { B[0] = 1; return; } Sqrt(A, B, (n + 1) &gt;&gt; 1); Inverse(B, InvB, n); Multiply(B, B, B2, n, n); for (RG int i = 0; i &lt; n; i++) InvB[i] *= InvTwo; for (RG int i = 0; i &lt; n; i++) B2[i] += A[i]; Multiply(B2, InvB, C2, n, n); for (RG int i = 0; i &lt; n; i++) B[i] = C2[i]; } Int AR[MAXN + 5], BR[MAXN + 5], InvBR[MAXN + 5], A2[MAXN + 5], CR[MAXN + 5], C3[MAXN + 5]; void Divide(const Int *A, const Int *B, Int *C, Int *R, const int &amp;n, const int &amp;m) { // C = A / B, R = A % B, A 不变, B 不变 for (RG int i = 0; i &lt; n; i++) AR[i] = A[n - i - 1], A2[i] = A[i]; for (RG int i = 0; i &lt; n - m + 1; i++) BR[i] = B[m - i - 1]; Inverse(BR, InvBR, n - m + 1); Multiply(AR, InvBR, CR, n, n - m + 1); for (int i = 0; i &lt; n - m + 1; i++) C[i] = CR[n - m - i]; Multiply(B, C, C3, m, n - m + 1); for (RG int i = 0; i &lt; m - 1; i++) R[i] = A[i] - C3[i]; } void Derivative(const Int *A, Int *B, const int &amp;n) { // B = A', A 不变 for (RG int i = 0; i &lt; n - 1; i++) B[i] = A[i + 1] * (i + 1); B[n - 1] = 0; } void Integral(const Int *A, Int *B, const int &amp;n) { // B = ∫A, A 不变 for (RG int i = 1; i &lt; n; i++) B[i] = A[i - 1] / i; B[0] = 0; } Int AD[MAXN + 5], InvA[MAXN + 5], C4[MAXN + 5]; void Ln(const Int *A, Int *B, const int &amp;n) { // B = ln A, A 不变 Derivative(A, AD, n); Inverse(A, InvA, n); Multiply(AD, InvA, C4, n, n); Integral(C4, B, n); } Int LnB[MAXN + 5], B3[MAXN + 5], B4[MAXN + 5]; void Exp(const Int *A, Int *B, const int &amp;n) { // B = e^A, A 不变 if (n == 1) { B[0] = 1; return; } Exp(A, B, (n + 1) &gt;&gt; 1); Ln(B, LnB, n); const int lim = ToPow(n + n - 1); for (int i = 0; i &lt; n; i++) B3[i] = A[i] - LnB[i], B4[i] = B[i]; B3[0] += One; Multiply(B3, B4, B, n, n); for (int i = n; i &lt; lim; i++) B[i] = 0; } Int kA[MAXN + 5]; void Pow(const Int *A, Int *B, const int &amp;n, const Int &amp;k) { // B = A^k, A 不变 for (int i = 0; i &lt; n; i++) kA[i] = A[i] * k; Exp(kA, B, n); } } int N; Int G[MAXN + 5], F[MAXN + 5]; Int Fac[MAXN + 5], Inv[MAXN + 5]; int main() { Polynomial::GetG0(MAXN); N = Read(); Fac[0] = 1; for (int i = 1; i &lt;= N; i++) Fac[i] = Fac[i - 1] * i; Inv[N] = One / Fac[N]; for (int i = N - 1; i &gt;= 0; i--) Inv[i] = Inv[i + 1] * (i + 1); G[0] = 1; for (int i = 1; i &lt;= N; i++) G[i] = (Two ^ ((LL)i * (i - 1) / 2)) * Inv[i]; Polynomial::Ln(G, F, N + 1); printf("%d", (F[N] * Fac[N]).x); return 0; }</code></pre>

页面列表

ITEM_HTML