| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 
 | const long double MPI = acos(-1);const int MOD = 998244353;
 
 
 namespace polynomial {
 int add(int x, int y) {
 x += y;
 return x >= MOD ? x - MOD : x;
 }
 int sub(int x, int y) {
 x -= y;
 return x < 0 ? x + MOD : x;
 }
 int qpow(int x, int y, int p = MOD) {
 int ret = 1;
 for (; y; y >>= 1, x = x * x % p)
 if (y & 1)
 ret = ret * x % p;
 return ret;
 }
 template <class _Tp>
 void change(_Tp* f, int len) {
 static int rev[MAXN] = {};
 for (int i = 0; i < len; ++i) {
 rev[i] = rev[i >> 1] >> 1;
 if (i & 1)
 rev[i] |= len >> 1;
 }
 for (int i = 0; i < len; ++i)
 if (i < rev[i])
 swap(f[i], f[rev[i]]);
 }
 void ntt(int* f, int len, int on) {
 change(f, len);
 for (int h = 2; h <= len; h <<= 1) {
 int gn = qpow(3, (MOD - 1) / h);
 for (int j = 0; j < len; j += h) {
 int g = 1;
 for (int k = j; k < j + h / 2; ++k) {
 int u = f[k], t = g * f[k + h / 2] % MOD;
 f[k] = add(u, t), f[k + h / 2] = sub(u, t);
 g = g * gn % MOD;
 }
 }
 }
 if (on == -1) {
 reverse(f + 1, f + len);
 int inv = qpow(len, MOD - 2);
 for (int i = 0; i < len; ++i)
 f[i] = f[i] * inv % MOD;
 }
 }
 int polymul(const int* f, int n, const int* g, int m, int* ans) {
 static int tf[MAXN] = {}, tg[MAXN] = {};
 int len = 1;
 while (len < n + m - 1)
 len <<= 1;
 copy(f, f + n, tf);
 fill(tf + n, tf + len, 0);
 copy(g, g + m, tg);
 fill(tg + m, tg + len, 0);
 ntt(tf, len, 1);
 ntt(tg, len, 1);
 for (int i = 0; i < len; ++i)
 tf[i] = tf[i] * tg[i] % MOD;
 ntt(tf, len, -1);
 copy(tf, tf + n + m - 1, ans);
 return n + m - 1;
 }
 int polyinv(const int* f, int n, int* ans) {
 static int tmp[MAXN] = {};
 int len = 1;
 while (len < n)
 len <<= 1;
 fill(ans, ans + len + len, 0);
 ans[0] = qpow(f[0], MOD - 2);
 for (int h = 2; h <= len; h <<= 1) {
 copy(f, f + h, tmp);
 fill(tmp + h, tmp + h + h, 0);
 ntt(tmp, h + h, 1);
 ntt(ans, h + h, 1);
 for (int i = 0; i < h + h; ++i)
 ans[i] = ans[i] * (2 - ans[i] * tmp[i] % MOD + MOD) % MOD;
 ntt(ans, h + h, -1);
 fill(ans + h, ans + h + h, 0);
 }
 return n;
 }
 int derivation(const int* f, int n, int* ans) {
 for (int i = 0; i < n - 1; ++i)
 ans[i] = f[i + 1] * (i + 1) % MOD;
 return ans[n - 1] = 0, n - 1;
 }
 int integral(const int* f, int n, int* ans) {
 for (int i = n; i >= 1; --i)
 ans[i] = f[i - 1] * qpow(i, MOD - 2) % MOD;
 return ans[0] = 0, n + 1;
 }
 int ln(const int* f, int n, int* ans) {
 static int tf[MAXN] = {}, tg[MAXN] = {};
 derivation(f, n, tf);
 polyinv(f, n, tg);
 polymul(tf, n - 1, tg, n, ans);
 integral(ans, n - 1, ans);
 fill(ans + n, ans + n + n, 0);
 return n;
 }
 int exp(const int* f, int n, int* ans) {
 static int tmp[MAXN] = {};
 ans[0] = 1, ans[1] = 0;
 for (int h = 2; h <= (n << 1); h <<= 1) {
 ln(ans, h, tmp);
 for (int i = 0; i < h; ++i)
 tmp[i] = add(i == 0, sub(f[i], tmp[i]));
 polymul(ans, h, tmp, h, ans);
 }
 return n;
 }
 };
 
 |