Skip to content

Commit 97c816d

Browse files
committed
update
1 parent 5fe02cb commit 97c816d

10 files changed

+180
-13
lines changed

docs/fps/famous-sequences.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
## 分割数
2+
3+
非負整数 $n$ の分割数 $p_n$ とは,$n$ をいくつかの正整数の和(順序を区別しない)で表す方法の数.
4+
5+
母関数は $\prod_{k=1}^{\infty}\frac{1}{1-x^k}$ である.
6+
7+
オイラーの五角数定理より
8+
$$\prod_{k=1}^{\infty}(1-x^k)=\sum_{k=-\infty}^{\infty}(-1)^kx^{k(3k-1)/2}$$
9+
であることを用いれば $O(N\log N)$ 時間で $p_0,p_1,\dots,p_N$ が列挙できる.
10+
11+
## 第一種スターリング数
12+
13+
$s(n,k)$ を以下で定める.
14+
$$x(x-1)\cdots(x-(n-1))=\sum_{k=0}^{n}s(n,k)x^k$$
15+
16+
$s(n,i)$ の $0\leq i\leq n$ での列挙が $O(n\log n)$ 時間でできる.
17+
- 分割統治をするが,一方の結果を Taylor Shift すればもう一方の結果を得られる.
18+
19+
また
20+
$$\sum_{i,j}s(i,j)\frac{x^i}{i!}y^j=(1+x)^y=\exp(y\log(1+x))=\sum_{j}(\log(1+x))^j\frac{y^j}{j!}$$
21+
となるので $s(i,k)$ の $k\leq i\leq n$ での列挙が $O((n-k)\log (n-k))$ 時間でできる.
22+
23+
## 第二種スターリング数
24+
25+
$S(n,k)$ を以下で定める.
26+
$$x^n=\sum_{k=0}^{n}S(n,k)x(x-1)\cdots(x-(k-1))$$
27+
28+
整数 $i$ について $x=i$ としたとき
29+
$$i^n=i![y^i]\left(\sum_{k=0}^{n}S(n,k)y^k\right)e^y$$
30+
と表示できるので
31+
$$\sum_{k=0}^{n}S(n,k)y^k=e^{-y}\left(\sum_{i=0}^{\infty}\frac{i^n}{i!}y^i\right)$$
32+
であり,$S(n,i)$ の $0\leq i\leq n$ での列挙が $O(n\log n)$ 時間でできる.
33+
また
34+
$$\sum_{i=0}^{\infty}\frac{i^n}{i!}y^i=n![x^n]\sum_{i=0}^{\infty}\frac{e^{ix}}{i!}y^i=n![x^n]\exp(e^xy)$$
35+
より
36+
$$\sum_{n,k}S(n,k)\frac{x^n}{n!}y^k=\exp((e^x-1)y)=\sum_{i\geq 0}(e^x-1)^i\frac{y^i}{i!}$$
37+
となるので $S(i,k)$ の $k\leq i\leq n$ での列挙が $O((n-k)\log (n-k))$ 時間でできる.

fps/famous-sequences.hpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#pragma once
2+
#include "modint/factorial.hpp"
3+
#include "modint/power-table.hpp"
4+
#include "fps/formal-power-series.hpp"
5+
#include "fps/taylor-shift.hpp"
6+
7+
template <class mint>
8+
FormalPowerSeries<mint> PartitionFunction(int n) {
9+
FormalPowerSeries<mint> g(n + 1);
10+
for (int k = 0; k * (3 * k - 1) / 2 <= n; k++) g[k * (3 * k - 1) / 2] += k & 1 ? -1 : 1;
11+
for (int k = 1; k * (3 * k + 1) / 2 <= n; k++) g[k * (3 * k + 1) / 2] += k & 1 ? -1 : 1;
12+
return g.inv(n + 1);
13+
}
14+
template <class mint>
15+
FormalPowerSeries<mint> FirstKindStirlingNumbers(int n) {
16+
FormalPowerSeries<mint> f{1};
17+
for (int l = 30; l >= 0; l--) {
18+
if (f.size() > 1) f *= TaylorShift(f, mint(-(n >> (l + 1))));
19+
if ((n >> l) & 1) f = (f << 1) - f * mint((n >> l) - 1);
20+
}
21+
return f;
22+
}
23+
template <class mint>
24+
FormalPowerSeries<mint> FirstKindStirlingNumbersFixedK(int n, int k) {
25+
using fact = Factorial<mint>;
26+
if (k > n) return FormalPowerSeries<mint>{};
27+
FormalPowerSeries<mint> f(n - k + 1);
28+
for (int i = 0; i < f.size(); i++) f[i] = fact::inv(i + 1) * (i & 1 ? -1 : 1);
29+
f = f.pow(k);
30+
f *= fact::fact_inv(k);
31+
for (int i = 0; i < f.size(); i++) f[i] *= fact::fact(i + k);
32+
return f;
33+
}
34+
template <class mint>
35+
FormalPowerSeries<mint> SecondKindStirlingNumbers(int n) {
36+
using fact = Factorial<mint>;
37+
FormalPowerSeries<mint> f(n + 1);
38+
for (int i = 0; i < f.size(); i++) f[i] = fact::fact_inv(i) * (i & 1 ? -1 : 1);
39+
FormalPowerSeries<mint> g(PowerTable<mint>(n, n));
40+
for (int i = 0; i < g.size(); i++) g[i] *= fact::fact_inv(i);
41+
f *= g;
42+
f.resize(n + 1);
43+
return f;
44+
}
45+
template <class mint>
46+
FormalPowerSeries<mint> SecondKindStirlingNumbersFixedK(int n, int k) {
47+
using fact = Factorial<mint>;
48+
if (k > n) return FormalPowerSeries<mint>{};
49+
FormalPowerSeries<mint> f(n - k + 1);
50+
for (int i = 0; i < f.size(); i++) f[i] = fact::fact_inv(i + 1);
51+
f = f.pow(k);
52+
f *= fact::fact_inv(k);
53+
for (int i = 0; i < f.size(); i++) f[i] *= fact::fact(i + k);
54+
return f;
55+
}
56+
57+
/**
58+
* @brief 有名数列
59+
* @docs docs/fps/famous-sequences.md
60+
*/

template/debug.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ void _show(int i, T name) {
1111
cerr << '\n';
1212
}
1313
template <class T1, class T2, class... T3>
14-
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
14+
void _show(int i, const T1& a, const T2& b, const T3&... c) {
1515
for (; a[i] != ',' && a[i] != '\0'; i++) cerr << a[i];
1616
cerr << ":" << b << " ";
1717
_show(i + 1, a, c...);

template/inout.hpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,28 @@ struct Fast {
88
} fast;
99

1010
template <class T1, class T2>
11-
istream &operator>>(istream &is, pair<T1, T2> &p) {
11+
istream& operator>>(istream& is, pair<T1, T2>& p) {
1212
return is >> p.first >> p.second;
1313
}
1414
template <class T1, class T2>
15-
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
15+
ostream& operator<<(ostream& os, const pair<T1, T2>& p) {
1616
return os << p.first << " " << p.second;
1717
}
1818
template <class T>
19-
istream &operator>>(istream &is, vector<T> &a) {
20-
for (auto &v : a) is >> v;
19+
istream& operator>>(istream& is, vector<T>& a) {
20+
for (auto& v : a) is >> v;
2121
return is;
2222
}
2323
template <class T>
24-
ostream &operator<<(ostream &os, const vector<T> &a) {
24+
ostream& operator<<(ostream& os, const vector<T>& a) {
2525
for (auto it = a.begin(); it != a.end();) {
2626
os << *it;
2727
if (++it != a.end()) os << " ";
2828
}
2929
return os;
3030
}
3131
template <class T>
32-
ostream &operator<<(ostream &os, const set<T> &st) {
32+
ostream& operator<<(ostream& os, const set<T>& st) {
3333
os << "{";
3434
for (auto it = st.begin(); it != st.end();) {
3535
os << *it;
@@ -39,7 +39,7 @@ ostream &operator<<(ostream &os, const set<T> &st) {
3939
return os;
4040
}
4141
template <class T1, class T2>
42-
ostream &operator<<(ostream &os, const map<T1, T2> &mp) {
42+
ostream& operator<<(ostream& os, const map<T1, T2>& mp) {
4343
os << "{";
4444
for (auto it = mp.begin(); it != mp.end();) {
4545
os << it->first << ":" << it->second;
@@ -51,13 +51,13 @@ ostream &operator<<(ostream &os, const map<T1, T2> &mp) {
5151

5252
void in() {}
5353
template <typename T, class... U>
54-
void in(T &t, U &...u) {
54+
void in(T& t, U&... u) {
5555
cin >> t;
5656
in(u...);
5757
}
5858
void out() { cout << "\n"; }
5959
template <typename T, class... U, char sep = ' '>
60-
void out(const T &t, const U &...u) {
60+
void out(const T& t, const U&... u) {
6161
cout << t;
6262
if (sizeof...(u)) cout << sep;
6363
out(u...);

template/util.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@ using i128 = __int128_t;
66
using u128 = __uint128_t;
77

88
template <class T, class S = T>
9-
S SUM(const vector<T> &a) {
9+
S SUM(const vector<T>& a) {
1010
return accumulate(ALL(a), S(0));
1111
}
1212
template <class T>
13-
inline bool chmin(T &a, T b) {
13+
inline bool chmin(T& a, T b) {
1414
if (a > b) {
1515
a = b;
1616
return true;
1717
}
1818
return false;
1919
}
2020
template <class T>
21-
inline bool chmax(T &a, T b) {
21+
inline bool chmax(T& a, T b) {
2222
if (a < b) {
2323
a = b;
2424
return true;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#define PROBLEM "https://judge.yosupo.jp/problem/partition_function"
2+
3+
#include "template/template.hpp"
4+
#include "modint/modint.hpp"
5+
using mint = ModInt<998244353>;
6+
#include "fps/fps-ntt-friendly.hpp"
7+
using fps = FormalPowerSeries<mint>;
8+
#include "fps/famous-sequences.hpp"
9+
10+
int main() {
11+
int n;
12+
in(n);
13+
out(PartitionFunction<mint>(n));
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#define PROBLEM "https://judge.yosupo.jp/problem/stirling_number_of_the_first_kind"
2+
3+
#include "template/template.hpp"
4+
#include "modint/modint.hpp"
5+
using mint = ModInt<998244353>;
6+
#include "fps/fps-ntt-friendly.hpp"
7+
using fps = FormalPowerSeries<mint>;
8+
#include "fps/famous-sequences.hpp"
9+
10+
int main() {
11+
int n;
12+
in(n);
13+
out(FirstKindStirlingNumbers<mint>(n));
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#define PROBLEM "https://judge.yosupo.jp/problem/stirling_number_of_the_first_kind_fixed_k"
2+
3+
#include "template/template.hpp"
4+
#include "modint/modint.hpp"
5+
using mint = ModInt<998244353>;
6+
#include "fps/fps-ntt-friendly.hpp"
7+
using fps = FormalPowerSeries<mint>;
8+
#include "fps/famous-sequences.hpp"
9+
10+
int main() {
11+
int n, k;
12+
in(n, k);
13+
out(FirstKindStirlingNumbersFixedK<mint>(n, k));
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#define PROBLEM "https://judge.yosupo.jp/problem/stirling_number_of_the_second_kind"
2+
3+
#include "template/template.hpp"
4+
#include "modint/modint.hpp"
5+
using mint = ModInt<998244353>;
6+
#include "fps/fps-ntt-friendly.hpp"
7+
using fps = FormalPowerSeries<mint>;
8+
#include "fps/famous-sequences.hpp"
9+
10+
int main() {
11+
int n;
12+
in(n);
13+
out(SecondKindStirlingNumbers<mint>(n));
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#define PROBLEM "https://judge.yosupo.jp/problem/stirling_number_of_the_second_kind_fixed_k"
2+
3+
#include "template/template.hpp"
4+
#include "modint/modint.hpp"
5+
using mint = ModInt<998244353>;
6+
#include "fps/fps-ntt-friendly.hpp"
7+
using fps = FormalPowerSeries<mint>;
8+
#include "fps/famous-sequences.hpp"
9+
10+
int main() {
11+
int n, k;
12+
in(n, k);
13+
out(SecondKindStirlingNumbersFixedK<mint>(n, k));
14+
}

0 commit comments

Comments
 (0)