1+ #pragma once
2+ #include " modint/factorial.hpp"
3+ #include " modint/mod-sqrt.hpp"
4+ #include " fps/formal-power-series.hpp"
5+
6+ namespace FPSSparse {
7+ template <class mint >
8+ FormalPowerSeries<mint> inv (map<int , mint> f, int n) {
9+ assert (f[0 ] != 0 );
10+ if (n == 0 ) return {};
11+ mint c = f[0 ].inv ();
12+ FormalPowerSeries<mint> g (n);
13+ g[0 ] = c;
14+ for (int i = 1 ; i < n; i++) {
15+ for (auto [j, v] : f)
16+ if (j <= i) g[i] -= v * g[i - j];
17+ g[i] *= c;
18+ }
19+ return g;
20+ }
21+ template <class mint >
22+ FormalPowerSeries<mint> exp (map<int , mint> f, int n) {
23+ assert (f[0 ] == 0 );
24+ if (n == 0 ) return {};
25+ FormalPowerSeries<mint> g (n);
26+ g[0 ] = 1 ;
27+ for (int i = 1 ; i < n; i++) {
28+ for (auto [j, v] : f)
29+ if (j <= i) g[i] += j * v * g[i - j];
30+ g[i] *= Factorial<mint>::inv (i);
31+ }
32+ return g;
33+ }
34+ template <class mint >
35+ FormalPowerSeries<mint> log (map<int , mint> f, int n) {
36+ assert (f[0 ] == 1 );
37+ if (n == 0 ) return {};
38+ FormalPowerSeries<mint> g (n);
39+ g[0 ] = 0 ;
40+ for (auto [j, v] : f)
41+ if (0 < j && j < n) g[j - 1 ] = v * j;
42+ for (int i = 1 ; i < n; i++) {
43+ for (auto [j, v] : f)
44+ if (0 < j && j <= i) g[i] -= v * g[i - j];
45+ }
46+ for (int i = n - 1 ; i > 0 ; i--) g[i] = g[i - 1 ] * Factorial<mint>::inv (i);
47+ g[0 ] = 0 ;
48+ return g;
49+ }
50+ template <class mint >
51+ FormalPowerSeries<mint> pow (map<int , mint> f, long long m, int n) {
52+ if (n == 0 ) return {};
53+ FormalPowerSeries<mint> g (n, 0 );
54+ if (m == 0 ) {
55+ g[0 ] = 1 ;
56+ return g;
57+ }
58+ if (f[0 ] == 0 ) {
59+ if (m >= n) return g;
60+ int s = 1 ;
61+ while (s < n && f[s] == 0 ) s++;
62+ if (s * m >= n) return g;
63+ map<int , mint> f1;
64+ for (auto [i, v] : f) f1[i - s] = v;
65+ auto g1 = pow (f1, m, int (n - s * m));
66+ copy (g1.begin (), g1.end (), g.begin () + int (s * m));
67+ return g;
68+ }
69+ g[0 ] = f[0 ].pow (m);
70+ mint c = f[0 ].inv ();
71+ for (int i = 1 ; i < n; i++) {
72+ for (auto [j, v] : f) {
73+ if (0 < j && j <= i) g[i] += j * f[j] * g[i - j] * m;
74+ if (0 < j && j < i) g[i] -= f[j] * (i - j) * g[i - j];
75+ }
76+ g[i] *= c * Factorial<mint>::inv (i);
77+ }
78+ return g;
79+ }
80+ template <class mint >
81+ FormalPowerSeries<mint> sqrt (map<int , mint> f, int n) {
82+ if (n == 0 ) return {};
83+ if (f.empty ()) return FormalPowerSeries<mint>(n, 0 );
84+ FormalPowerSeries<mint> g (n, 0 );
85+ if (f[0 ] == 0 ) {
86+ int s = 1 ;
87+ while (s < n * 2 && f[s] == 0 ) s++;
88+ if (s & 1 ) return {};
89+ s /= 2 ;
90+ if (s >= n) return g;
91+ map<int , mint> f1;
92+ for (auto [i, v] : f) f1[i - s * 2 ] = v;
93+ auto g1 = sqrt (f1, int (n - s));
94+ if (g1.empty ()) return {};
95+ copy (g1.begin (), g1.end (), g.begin () + s);
96+ return g;
97+ }
98+ long long sq = ModSqrt (f[0 ].val (), mint::get_mod ());
99+ if (sq < 0 ) return {};
100+ g[0 ] = sq;
101+ mint c = f[0 ].inv (), inv2 = mint (2 ).inv ();
102+ for (int i = 1 ; i < n; i++) {
103+ for (auto [j, v] : f) {
104+ if (0 < j && j <= i) g[i] += j * f[j] * g[i - j] * inv2;
105+ if (0 < j && j < i) g[i] -= f[j] * (i - j) * g[i - j];
106+ }
107+ g[i] *= c * Factorial<mint>::inv (i);
108+ }
109+ return g;
110+ }
111+ }; // namespace FPSSparse
112+
113+ /* *
114+ * @brief Sparse な FPS 演算
115+ * @docs docs/fps/sparse.md
116+ */
0 commit comments