QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#739977 | #5448. 另一个欧拉数问题 | I_be_wanna | 100 ✓ | 1018ms | 28884kb | C++20 | 53.8kb | 2024-11-13 00:08:02 | 2024-11-13 00:08:03 |
Judging History
answer
/*#pragma GCC optimize ("Ofast")
#include <bits/stdc++.h>
using ll = long long;
using namespace std;
const int BUFF_SIZE = 1 << 20;
char BUFF[BUFF_SIZE], *BB, *BE;
char gc() {
return BB == BE ? (BE = (BB = BUFF) + fread(BUFF, 1, BUFF_SIZE, stdin), BB == BE ? EOF : *BB++) : *BB++;
}
void read() {}
template<class T, class ...Ts>
void read(T &x, Ts &...args) {
x = 0;
char ch = 0, w = 0;
while (ch < '0' || ch > '9')
w |= ch == '-', ch = gc();
while (ch >= '0' && ch <= '9')
x = x * 10 + (ch ^ '0'), ch = gc();
if (w) x = -x;
read(args...);
}
const int mod = 998244353, K = 23, Root = 31;
int norm(int x) { return x >= mod ? x - mod : x; }
int reduce(int x) { return x < 0 ? x + mod : x; }
int neg(int x) { return x ? mod - x : 0; }
int quo2(int x) { return (x + (x & 1 ? mod : 0)) >> 1; }
void add(int &x, int y) { if ((x += y - mod) < 0) x += mod; }
void sub(int &x, int y) { if ((x -= y) < 0) x += mod; }
void fam(int &x, int y, int z) { x = (x + (ll)y * z) % mod; }
int mpow(int a, int b) {
int ret = 1;
for (; b; b >>= 1) {
if (b & 1) ret = (ll)ret * a % mod;
a = (ll)a * a % mod;
}
return ret;
}
const int BRUTE_N2_LIMIT = 50;
struct NumberTheory {
typedef pair<int, int> P2_Field;
mt19937 rng;
NumberTheory(): rng(chrono::steady_clock::now().time_since_epoch().count()) {}
void exGcd(int a, int b, int &x, int &y) {
if (!b) {
x = 1, y = 0;
return;
}
exGcd(b, a % b, y, x), y -= a / b * x;
}
int inv(int a, int p = mod) {
int x, y;
exGcd(a, p, x, y);
if (x < 0) x += p;
return x;
}
template<class Integer>
bool quadRes(Integer a, Integer b) {
if (a <= 1) return 1;
while (a % 4 == 0) a /= 4;
if (a % 2 == 0) return (b % 8 == 1 || b % 8 == 7) == quadRes(a / 2, b);
return ((a - 1) % 4 == 0 || (b - 1) % 4 == 0) == quadRes(b % a, a);
}
int sqrt(int x, int p = mod) {
if (p == 2 || x <= 1) return x;
int w, v, k = (p + 1) / 2;
do w = rng() % p;
while (quadRes(v = ((ll)w * w - x + p) % p, p));
P2_Field res(1, 0), a(w, 1);
for (; k; k >>= 1) {
if (k & 1)
res = P2_Field(
((ll)res.first * a.first + (ll)res.second * a.second % p * v) % p,
((ll)res.first * a.second + (ll)res.second * a.first) % p
);
a = P2_Field(((ll)a.first * a.first + (ll)a.second * a.second % p * v) % p, 2LL * a.first * a.second % p);
}
return min(res.first, p - res.first);
}
} nt;
namespace Simple {
int n = 1;
vector<int> fac({1, 1}), ifac({1, 1}), inv({0, 1});
void build(int m) {
n = m;
fac.resize(n + 1), ifac.resize(n + 1), inv.resize(n + 1);
inv[1] = 1;
for (int i = 2; i <= n; ++i) inv[i] = (ll)(mod - mod / i) * inv[mod % i] % mod;
fac[0] = ifac[0] = 1;
for (int i = 1; i <= n; ++i) fac[i] = (ll)fac[i - 1] * i % mod, ifac[i] = (ll)ifac[i - 1] * inv[i] % mod;
}
void check(int k) {
int m = n;
if (k > m) {
while (k > m) m <<= 1;
build(m);
}
}
int gfac(int k) {
check(k);
return fac[k];
}
int gifac(int k) {
check(k);
return ifac[k];
}
int ginv(int k) {
check(k);
return inv[k];
}
}
struct SimpleSequence {
function<int(int)> func;
SimpleSequence(const function<int(int)> &func): func(func) {}
int operator[](int k) const { return func(k); }
} gfac(Simple::gfac), gifac(Simple::gifac), ginv(Simple::ginv);
int binom(int n, int m) {
if (m > n || m < 0) return 0;
return (ll)gfac[n] * gifac[m] % mod * gifac[n - m] % mod;
}
namespace NTT {
int L = -1;
vector<int> root;
void init(int l) {
L = l;
root.resize((1 << L) + 1);
int n = 1 << L, *w = root.data();
w[0] = 1, w[1 << L] = mpow(Root, 1 << (K - 2 - L));
for (int i = L; i; --i) w[1 << (i - 1)] = (ll)w[1 << i] * w[1 << i] % mod;
for (int i = 1; i < n; ++i) w[i] = (ll)w[i & (i - 1)] * w[i & -i] % mod;
}
void DIF(int *a, int l) {
int n = 1 << l;
for (int len = n >> 1; len; len >>= 1)
for (int *j = a, *o = root.data(); j != a + n; j += len << 1, ++o)
for (int *k = j; k != j + len; ++k) {
int r = (ll)*o * k[len] % mod;
k[len] = reduce(*k - r), add(*k, r);
}
}
void DIT(int *a, int l) {
int n = 1 << l;
for (int len = 1; len < n; len <<= 1)
for (int *j = a, *o = root.data(); j != a + n; j += len << 1, ++o)
for (int *k = j; k != j + len; ++k) {
int r = norm(*k + k[len]);
k[len] = (ll)*o * (*k - k[len] + mod) % mod, *k = r;
}
}
void fft(int *a, int lgn, int d = 1) {
if (L < lgn) init(lgn);
int n = 1 << lgn;
if (d == 1) DIF(a, lgn);
else {
DIT(a, lgn), reverse(a + 1, a + n);
int nInv = mod - (mod - 1) / n;
for (int i = 0; i < n; ++i) a[i] = (ll)a[i] * nInv % mod;
}
}
}
struct poly {
vector<int> a;
poly(ll v = 0): a(1) {
if ((v %= mod) < 0) v += mod;
a[0] = v;
}
poly(const poly &o): a(o.a) {}
poly(const vector<int> &o): a(o) {}
poly(initializer_list<int> o): a(o) {}
operator vector<int>() const { return a; }
int operator[](int k) const { return k < a.size() ? a[k] : 0; }
int &operator[](int k) {
if (k >= a.size()) a.resize(k + 1);
return a[k];
}
int deg() const { return (int)a.size() - 1; }
void redeg(int d) { a.resize(d + 1); }
int size() const { return a.size(); }
void resize(int s) { a.resize(s); }
poly slice(int d) const {
if (d < a.size()) return vector<int>(a.begin(), a.begin() + d + 1);
vector<int> ret = a;
ret.resize(d + 1);
return ret;
}
poly shift(int k) const {
if (size() + k <= 0) return 0;
vector<int> ret(size() + k);
for (int i = max(0, k); i < ret.size(); ++i) ret[i] = a[i - k];
return ret;
}
int eval(int x) const {
int ret = 0;
for (int i = deg(); i >= 0; --i)
ret = ((ll)ret * x + a[i]) % mod;
return ret;
}
bool operator<(const poly &o) const {
for (int i = 0; i <= min(deg(), o.deg()); ++i)
if (a[i] != o[i])
return a[i] < o[i];
return deg() < o.deg();
}
int *base() { return a.data(); }
const int *base() const { return a.data(); }
poly println(FILE *fp = stdout) const {
for (int i = 0; i < a.size(); ++i) fprintf(fp, "%d%c", a[i], " \n"[i == a.size() - 1]);
return *this;
}
poly &operator+=(const poly &o) {
if (o.size() > a.size()) a.resize(o.size());
for (int i = 0; i < o.size(); ++i) add(a[i], o[i]);
return *this;
}
poly operator+(const poly &o) const {
poly ret(a);
ret += o;
return ret;
}
poly operator-() const {
poly ret = a;
for (int i = 0; i < a.size(); ++i) ret[i] = neg(ret[i]);
return ret;
}
poly &operator-=(const poly &o) { return operator+=(-o); }
poly operator-(const poly &o) { return operator+(-o); }
poly operator*(const poly &) const;
poly operator/(const poly &) const;
poly operator%(const poly &) const;
poly &operator*=(const poly &o) {
*this = operator*(o);
return *this;
}
poly &operator/=(const poly &o) {
*this = operator/(o);
return *this;
}
poly &operator%=(const poly &o) {
*this = operator%(o);
return *this;
}
poly deriv() const;
poly integ() const;
poly inv() const;
poly sqrt() const;
poly ln() const;
poly exp() const;
poly srcExp() const;
pair<poly, poly> sqrti() const;
pair<poly, poly> expi() const;
poly quo(const poly &) const;
pair<poly, poly> iquo() const;
pair<poly, poly> div(const poly &) const;
poly taylor(int k) const;
poly pow(int k) const;
poly exp(int k) const;
};
poly zeroes(int d) { return vector<int>(d + 1); }
namespace NTT {
void fft(poly &a, int lgn, int d = 1) { fft(a.base(), lgn, d); }
void fft(vector<int> &a, int lgn, int d = 1) { fft(a.data(), lgn, d); }
}
using NTT::fft;
struct SemiRelaxedConvolution {
static const int LG = 19;
static const int B = 16;
void run(int *f, const int *g, int n, const function<void(int)> &relax) {
vector<vector<int>> save(LG + 1);
function<void(int, int)> divideConquer = [&](int l, int r) {
if (r - l <= BRUTE_N2_LIMIT) {
for (int i = l + 1; i <= r; ++i) {
for (int j = l; j < i; ++j) fam(f[i], f[j], g[i - j]);
relax(i);
}
return;
}
int d = (r - l) / B + 1, lgd = 0, lg;
while ((1 << lgd) <= d * 2) ++lgd;
d = (1 << (lgd - 1)) - 1, lg = (r - l + d - 1) / d;
vector<int> dft = save[lgd];
dft.resize(lg << (lgd + 1));
for (int i = lg << lgd; i < (lg << (lgd + 1)); ++i) dft[i] = 0;
int ef = lg;
for (int i = 0; i < lg; ++i) {
if ((i << lgd) < save[lgd].size()) continue;
if ((i + 2) * d >= l) --ef;
for (int j = 0; j <= min(d * 2, n - i * d); ++j) dft[(i << lgd) + j] = g[i * d + j];
fft(dft.data() + (i << lgd), lgd);
}
for (int i = 0; i < lg; ++i) {
if (i) fft(dft.data() + ((lg + i) << lgd), lgd, -1);
for (int j = 1; j <= min(d, r - l - i * d); ++j) add(f[l + i * d + j], dft[((lg + i) << lgd) + d + j]);
divideConquer(l + i * d, min(l + (i + 1) * d, r));
if (i + 1 < lg) {
for (int j = 0; j < d; ++j) dft[((lg + i) << lgd) + j] = f[l + i * d + j];
for (int j = d; j < (1 << lgd); ++j) dft[((lg + i) << lgd) + j] = 0;
fft(dft.data() + ((lg + i) << lgd), lgd);
}
for (int j = i + 1; j < lg; ++j)
for (int k = 0; k < (1 << lgd); ++k)
fam(dft[((lg + j) << lgd) + k], dft[((j - i - 1) << lgd) + k], dft[((lg + i) << lgd) + k]);
}
};
relax(0), divideConquer(0, n);
}
} src;
poly poly::srcExp() const {
int n = deg();
poly f, g;
f.redeg(n), g.redeg(n);
for (int i = 0; i <= n; ++i) g[i] = (ll)a[i] * i % mod;
src.run(f.base(), g.base(), n, [&](int i) {
if (i == 0) f[i] = 1;
else f[i] = (ll)f[i] * ginv[i] % mod;
});
return f;
}
struct Newton {
void inv(const poly &f, const poly &dftf, poly &g, const poly &dftg, int t) {
int n = 1 << t;
poly prod = dftf;
for (int i = 0; i < (n << 1); ++i) prod[i] = (ll)prod[i] * dftg[i] % mod;
fft(prod, t + 1, -1);
memset(prod.base(), 0, sizeof(int) << t);
fft(prod, t + 1);
for (int i = 0; i < (n << 1); ++i) prod[i] = (ll)prod[i] * dftg[i] % mod;
fft(prod, t + 1, -1);
for (int i = 0; i < n; ++i) prod[i] = 0;
g -= prod;
}
void inv(const poly &f, const poly &dftf, poly &g, int t) {
poly dftg(g);
dftg.resize(2 << t);
fft(dftg, t + 1);
inv(f, dftf, g, dftg, t);
}
void inv(const poly &f, poly &g, int t) {
poly dftf(f), dftg(g);
dftf.resize(2 << t), dftg.resize(2 << t);
fft(dftf, t + 1), fft(dftg, t + 1);
inv(f, dftf, g, dftg, t);
}
void sqrt(const poly &f, poly &g, poly &dftg, poly &h, int t) {
for (int i = 0; i < (1 << t); ++i) dftg[i] = (ll)dftg[i] * dftg[i] % mod;
fft(dftg, t, -1);
dftg -= f;
for (int i = 0; i < (1 << t); ++i) add(dftg[i | (1 << t)], dftg[i]), dftg[i] = 0;
fft(dftg, t + 1);
poly tmp = h;
tmp.resize(2 << t);
fft(tmp, t + 1);
for (int i = 0; i < (2 << t); ++i) tmp[i] = (ll)tmp[i] * dftg[i] % mod;
fft(tmp, t + 1, -1);
memset(tmp.base(), 0, sizeof(int) << t);
g -= tmp * ginv[2];
}
void exp(const poly &f, poly &g, poly &dftg, poly &h, int t) {
poly dfth = h;
fft(dfth, t);
poly dg = g.deriv().slice((1 << t) - 1);
fft(dg, t);
poly tmp = zeroes((1 << t) - 1);
for (int i = 0; i < (1 << t); ++i) tmp[i] = (ll)dftg[i] * dfth[i] % mod, dg[i] = (ll)dg[i] * dfth[i] % mod;
fft(tmp, t, -1), fft(dg, t, -1);
sub(tmp[0], 1);
dg.resize(2 << t);
poly df0 = f.deriv().slice((1 << t) - 1);
df0[(1 << t) - 1] = 0;
for (int i = 0; i < (1 << t); ++i) dg[i | (1 << t)] = reduce(dg[i] - df0[i]);
memcpy(dg.base(), df0.base(), sizeof(int) * ((1 << t) - 1));
tmp.resize(2 << t), fft(tmp, t + 1);
df0.resize(2 << t), fft(df0, t + 1);
for (int i = 0; i < (2 << t); ++i) df0[i] = (ll)df0[i] * tmp[i] % mod;
fft(df0, t + 1, -1);
for (int i = 0; i < (1 << t); ++i) df0[i | (1 << t)] = df0[i], df0[i] = 0;
dg = (dg - df0).integ().slice((2 << t) - 1) - f;
fft(dg, t + 1);
for (int i = 0; i < (2 << t); ++i) tmp[i] = (ll)dg[i] * dftg[i] % mod;
fft(tmp, t + 1, -1);
g.resize(2 << t);
for (int i = 1 << t; i < (2 << t); ++i) g[i] = neg(tmp[i]);
}
} nit;
struct Transposition {
vector<int> _mul(int l, vector<int> res, const poly &b) {
vector<int> tmp(1 << l);
memcpy(tmp.data(), b.base(), sizeof(int) * (b.deg() + 1));
reverse(tmp.begin() + 1, tmp.end());
fft(tmp.data(), l);
for (int i = 0; i < (1 << l); ++i) res[i] = (ll)res[i] * tmp[i] % mod;
fft(res.data(), l, -1);
return res;
}
poly bfMul(const poly &a, const poly &b) {
int n = a.deg(), m = b.deg();
poly ret = zeroes(n - m);
for (int i = 0; i <= n - m; ++i)
for (int j = 0; j <= m; ++j) ret[i] = (ret[i] + (ll)a[i + j] * b[j]) % mod;
return ret;
}
poly mul(const poly &a, const poly &b) {
if (a.deg() < b.deg()) return 0;
if (a.deg() <= BRUTE_N2_LIMIT) return bfMul(a, b);
int l = 0;
while ((1 << l) <= a.deg()) ++l;
vector<int> res(1 << l);
memcpy(res.data(), a.base(), sizeof(int) * (a.deg() + 1));
fft(res.data(), l);
res = _mul(l, res, b);
res.resize(a.deg() - b.deg() + 1);
return res;
}
pair<poly, poly> mul2(const poly &a, const poly &b1, const poly &b2) {
if (a.deg() <= BRUTE_N2_LIMIT) return make_pair(bfMul(a, b1), bfMul(a, b2));
int l = 0;
while ((1 << l) <= a.deg()) ++l;
vector<int> fa(1 << l);
memcpy(fa.data(), a.base(), sizeof(int) * (a.deg() + 1));
fft(fa.data(), l);
vector<int> res1 = _mul(l, fa, b1), res2 = _mul(l, fa, b2);
res1.resize(a.deg() - b1.deg() + 1), res2.resize(a.deg() - b2.deg() + 1);
return {res1, res2};
}
vector<int> ls, rs, pos;
vector<poly> p, q;
void _build(int n) {
ls.assign(n * 2 - 1, 0), rs.assign(n * 2 - 1, 0), p.assign(n * 2 - 1, 0), q.assign(n * 2 - 1, 0), pos.resize(n);
int cnt = 0;
function<int(int, int)> dfs = [&](int l, int r) {
if (l == r) { pos[l] = cnt; return cnt++; }
int ret = cnt++;
int mid = (l + r) >> 1;
ls[ret] = dfs(l, mid), rs[ret] = dfs(mid + 1, r);
return ret;
};
dfs(0, n - 1);
}
vector<int> _eval(vector<int> f, const vector<int> &x) {
int n = f.size();
_build(n);
for (int i = 0; i < n; ++i) q[pos[i]] = {1, neg(x[i])};
for (int i = n * 2 - 2; i >= 0; --i)
if (ls[i]) q[i] = q[ls[i]] * q[rs[i]];
f.resize(n * 2);
p[0] = mul(f, q[0].inv());
for (int i = 0; i < n * 2 - 1; ++i)
if (ls[i]) tie(p[ls[i]], p[rs[i]]) = mul2(p[i], q[rs[i]], q[ls[i]]);
vector<int> ret(n);
for (int i = 0; i < n; ++i) ret[i] = p[pos[i]][0];
return ret;
}
vector<int> eval(const poly &f, const vector<int> &x) {
int n = f.deg() + 1, m = x.size();
vector<int> tmpf = f.a, tmpx = x;
tmpf.resize(max(n, m)), tmpx.resize(max(n, m));
vector<int> ret = _eval(tmpf, tmpx);
ret.resize(m);
return ret;
}
poly inter(const vector<int> &x, const vector<int> &y) {
int n = x.size();
_build(n);
for (int i = 0; i < n; ++i) q[pos[i]] = {1, norm(mod - x[i])};
for (int i = n * 2 - 2; i >= 0; --i)
if (ls[i]) q[i] = q[ls[i]] * q[rs[i]];
poly tmp = q[0];
reverse(tmp.a.begin(), tmp.a.end());
vector<int> f = tmp.deriv().a;
f.resize(n * 2);
p[0] = mul(f, q[0].inv());
for (int i = 0; i < n * 2 - 1; ++i)
if (ls[i]) tie(p[ls[i]], p[rs[i]]) = mul2(p[i], q[rs[i]], q[ls[i]]);
for (int i = 0; i < n; ++i) p[pos[i]] = nt.inv(p[pos[i]][0]) * (ll)y[i] % mod;
for (int i = 0; i < n * 2 - 1; ++i) reverse(q[i].a.begin(), q[i].a.end());
for (int i = n * 2 - 2; i >= 0; --i)
if (ls[i]) p[i] = p[ls[i]] * q[rs[i]] + p[rs[i]] * q[ls[i]];
return p[0];
}
} tp;
struct FactorialPolynomials {
pair<poly, poly> mul2(const poly &a, const poly &b1, const poly &b2) {
int n = a.deg() + max(b1.deg(), b2.deg());
if (n <= BRUTE_N2_LIMIT) return {a * b1, a * b2};
int l = 0;
while ((1 << l) <= n) ++l;
vector<int> fa(1 << l);
memcpy(fa.data(), a.base(), sizeof(int) * (a.deg() + 1));
fft(fa.data(), l);
vector<int> res1(1 << l), res2(1 << l);
memcpy(res1.data(), b1.base(), sizeof(int) * (b1.deg() + 1)), memcpy(res2.data(), b2.base(), sizeof(int) * (b2.deg() + 1));
fft(res1.data(), l), fft(res2.data(), l);
for (int i = 0; i < (1 << l); ++i) res1[i] = (ll)res1[i] * fa[i] % mod, res2[i] = (ll)res2[i] * fa[i] % mod;
fft(res1.data(), l, -1), fft(res2.data(), l, -1);
res1.resize(a.deg() + b1.deg() + 1), res2.resize(a.deg() + b2.deg() + 1);
return {res1, res2};
}
vector<int> ls, rs, pos;
vector<poly> p, q;
void _build(int n) {
ls.assign(n * 2 - 1, 0), rs.assign(n * 2 - 1, 0), p.assign(n * 2 - 1, 0), q.assign(n * 2 - 1, 0), pos.resize(n);
int cnt = 0;
function<int(int, int)> dfs = [&](int l, int r) {
if (l == r) { pos[l] = cnt; return cnt++; }
int ret = cnt++;
int mid = (l + r) >> 1;
ls[ret] = dfs(l, mid), rs[ret] = dfs(mid + 1, r);
return ret;
};
dfs(0, n - 1);
}
vector<int> toPoly(vector<int> f) {
int n = f.size();
_build(n);
for (int i = 0; i < n; ++i) p[pos[i]] = f[i], q[pos[i]] = {neg(i), 1};
for (int i = n * 2 - 2; i >= 0; --i)
if (ls[i]) tie(p[i], q[i]) = mul2(q[ls[i]], p[rs[i]], q[rs[i]]), p[i] += p[ls[i]];
return p[0];
}
vector<int> lagrange(int x, vector<int> y) {
int m = y.size(), n = m * 2 - 1;
vector<int> tinv(n);
if (x == m)
for (int i = 0; i < n; ++i) tinv[i] = ginv[x - (m - 1 - i)];
else {
vector<int> tfac(n), tifac(n);
tfac[0] = reduce(x - (m - 1));
for (int i = 1; i < n; ++i) tfac[i] = (ll)tfac[i - 1] * (x - (m - 1 - i) + mod) % mod;
tifac[n - 1] = nt.inv(tfac[n - 1]);
for (int i = n - 1; i; --i) tifac[i - 1] = (ll)tifac[i] * (x - (m - 1 - i) + mod) % mod;
tinv[0] = tifac[0];
for (int i = 1; i < n; ++i) tinv[i] = (ll)tifac[i] * tfac[i - 1] % mod;
}
for (int i = 0; i < m; ++i)
y[i] = (ll)((m - i) & 1 ? y[i] : mod - y[i]) * gifac[i] % mod * gifac[m - 1 - i] % mod;
vector<int> ret(m);
if (n <= BRUTE_N2_LIMIT) {
for (int i = 0; i <= m; ++i) ans = (ans + (ll)p[i] * q[m - i]) % mod;
ans = (ll)ans * ginv[m + 1] % mod;
printf("%d\n", ans);
}*/#pragma GCC optimize ("Ofast")
#include <bits/stdc++.h>
using ll = long long;
using namespace std;
const int BUFF_SIZE = 1 << 20;
char BUFF[BUFF_SIZE], *BB, *BE;
char gc() {
return BB == BE ? (BE = (BB = BUFF) + fread(BUFF, 1, BUFF_SIZE, stdin), BB == BE ? EOF : *BB++) : *BB++;
}
void read() {}
template<class T, class ...Ts>
void read(T &x, Ts &...args) {
x = 0;
char ch = 0, w = 0;
while (ch < '0' || ch > '9')
w |= ch == '-', ch = gc();
while (ch >= '0' && ch <= '9')
x = x * 10 + (ch ^ '0'), ch = gc();
if (w) x = -x;
read(args...);
}
const int mod = 998244353, K = 23, Root = 31;
int norm(int x) { return x >= mod ? x - mod : x; }
int reduce(int x) { return x < 0 ? x + mod : x; }
int neg(int x) { return x ? mod - x : 0; }
int quo2(int x) { return (x + (x & 1 ? mod : 0)) >> 1; }
void add(int &x, int y) { if ((x += y - mod) < 0) x += mod; }
void sub(int &x, int y) { if ((x -= y) < 0) x += mod; }
void fam(int &x, int y, int z) { x = (x + (ll)y * z) % mod; }
int mpow(int a, int b) {
int ret = 1;
for (; b; b >>= 1) {
if (b & 1) ret = (ll)ret * a % mod;
a = (ll)a * a % mod;
}
return ret;
}
const int BRUTE_N2_LIMIT = 50;
struct NumberTheory {
typedef pair<int, int> P2_Field;
mt19937 rng;
NumberTheory(): rng(chrono::steady_clock::now().time_since_epoch().count()) {}
void exGcd(int a, int b, int &x, int &y) {
if (!b) {
x = 1, y = 0;
return;
}
exGcd(b, a % b, y, x), y -= a / b * x;
}
int inv(int a, int p = mod) {
int x, y;
exGcd(a, p, x, y);
if (x < 0) x += p;
return x;
}
template<class Integer>
bool quadRes(Integer a, Integer b) {
if (a <= 1) return 1;
while (a % 4 == 0) a /= 4;
if (a % 2 == 0) return (b % 8 == 1 || b % 8 == 7) == quadRes(a / 2, b);
return ((a - 1) % 4 == 0 || (b - 1) % 4 == 0) == quadRes(b % a, a);
}
int sqrt(int x, int p = mod) {
if (p == 2 || x <= 1) return x;
int w, v, k = (p + 1) / 2;
do w = rng() % p;
while (quadRes(v = ((ll)w * w - x + p) % p, p));
P2_Field res(1, 0), a(w, 1);
for (; k; k >>= 1) {
if (k & 1)
res = P2_Field(
((ll)res.first * a.first + (ll)res.second * a.second % p * v) % p,
((ll)res.first * a.second + (ll)res.second * a.first) % p
);
a = P2_Field(((ll)a.first * a.first + (ll)a.second * a.second % p * v) % p, 2LL * a.first * a.second % p);
}
return min(res.first, p - res.first);
}
} nt;
namespace Simple {
int n = 1;
vector<int> fac({1, 1}), ifac({1, 1}), inv({0, 1});
void build(int m) {
n = m;
fac.resize(n + 1), ifac.resize(n + 1), inv.resize(n + 1);
inv[1] = 1;
for (int i = 2; i <= n; ++i) inv[i] = (ll)(mod - mod / i) * inv[mod % i] % mod;
fac[0] = ifac[0] = 1;
for (int i = 1; i <= n; ++i) fac[i] = (ll)fac[i - 1] * i % mod, ifac[i] = (ll)ifac[i - 1] * inv[i] % mod;
}
void check(int k) {
int m = n;
if (k > m) {
while (k > m) m <<= 1;
build(m);
}
}
int gfac(int k) {
check(k);
return fac[k];
}
int gifac(int k) {
check(k);
return ifac[k];
}
int ginv(int k) {
check(k);
return inv[k];
}
}
struct SimpleSequence {
function<int(int)> func;
SimpleSequence(const function<int(int)> &func): func(func) {}
int operator[](int k) const { return func(k); }
} gfac(Simple::gfac), gifac(Simple::gifac), ginv(Simple::ginv);
int binom(int n, int m) {
if (m > n || m < 0) return 0;
return (ll)gfac[n] * gifac[m] % mod * gifac[n - m] % mod;
}
namespace NTT {
int L = -1;
vector<int> root;
void init(int l) {
L = l;
root.resize((1 << L) + 1);
int n = 1 << L, *w = root.data();
w[0] = 1, w[1 << L] = mpow(Root, 1 << (K - 2 - L));
for (int i = L; i; --i) w[1 << (i - 1)] = (ll)w[1 << i] * w[1 << i] % mod;
for (int i = 1; i < n; ++i) w[i] = (ll)w[i & (i - 1)] * w[i & -i] % mod;
}
void DIF(int *a, int l) {
int n = 1 << l;
for (int len = n >> 1; len; len >>= 1)
for (int *j = a, *o = root.data(); j != a + n; j += len << 1, ++o)
for (int *k = j; k != j + len; ++k) {
int r = (ll)*o * k[len] % mod;
k[len] = reduce(*k - r), add(*k, r);
}
}
void DIT(int *a, int l) {
int n = 1 << l;
for (int len = 1; len < n; len <<= 1)
for (int *j = a, *o = root.data(); j != a + n; j += len << 1, ++o)
for (int *k = j; k != j + len; ++k) {
int r = norm(*k + k[len]);
k[len] = (ll)*o * (*k - k[len] + mod) % mod, *k = r;
}
}
void fft(int *a, int lgn, int d = 1) {
if (L < lgn) init(lgn);
int n = 1 << lgn;
if (d == 1) DIF(a, lgn);
else {
DIT(a, lgn), reverse(a + 1, a + n);
int nInv = mod - (mod - 1) / n;
for (int i = 0; i < n; ++i) a[i] = (ll)a[i] * nInv % mod;
}
}
}
struct poly {
vector<int> a;
poly(ll v = 0): a(1) {
if ((v %= mod) < 0) v += mod;
a[0] = v;
}
poly(const poly &o): a(o.a) {}
poly(const vector<int> &o): a(o) {}
poly(initializer_list<int> o): a(o) {}
operator vector<int>() const { return a; }
int operator[](int k) const { return k < a.size() ? a[k] : 0; }
int &operator[](int k) {
if (k >= a.size()) a.resize(k + 1);
return a[k];
}
int deg() const { return (int)a.size() - 1; }
void redeg(int d) { a.resize(d + 1); }
int size() const { return a.size(); }
void resize(int s) { a.resize(s); }
poly slice(int d) const {
if (d < a.size()) return vector<int>(a.begin(), a.begin() + d + 1);
vector<int> ret = a;
ret.resize(d + 1);
return ret;
}
poly shift(int k) const {
if (size() + k <= 0) return 0;
vector<int> ret(size() + k);
for (int i = max(0, k); i < ret.size(); ++i) ret[i] = a[i - k];
return ret;
}
int eval(int x) const {
int ret = 0;
for (int i = deg(); i >= 0; --i)
ret = ((ll)ret * x + a[i]) % mod;
return ret;
}
bool operator<(const poly &o) const {
for (int i = 0; i <= min(deg(), o.deg()); ++i)
if (a[i] != o[i])
return a[i] < o[i];
return deg() < o.deg();
}
int *base() { return a.data(); }
const int *base() const { return a.data(); }
poly println(FILE *fp = stdout) const {
for (int i = 0; i < a.size(); ++i) fprintf(fp, "%d%c", a[i], " \n"[i == a.size() - 1]);
return *this;
}
poly &operator+=(const poly &o) {
if (o.size() > a.size()) a.resize(o.size());
for (int i = 0; i < o.size(); ++i) add(a[i], o[i]);
return *this;
}
poly operator+(const poly &o) const {
poly ret(a);
ret += o;
return ret;
}
poly operator-() const {
poly ret = a;
for (int i = 0; i < a.size(); ++i) ret[i] = neg(ret[i]);
return ret;
}
poly &operator-=(const poly &o) { return operator+=(-o); }
poly operator-(const poly &o) { return operator+(-o); }
poly operator*(const poly &) const;
poly operator/(const poly &) const;
poly operator%(const poly &) const;
poly &operator*=(const poly &o) {
*this = operator*(o);
return *this;
}
poly &operator/=(const poly &o) {
*this = operator/(o);
return *this;
}
poly &operator%=(const poly &o) {
*this = operator%(o);
return *this;
}
poly deriv() const;
poly integ() const;
poly inv() const;
poly sqrt() const;
poly ln() const;
poly exp() const;
poly srcExp() const;
pair<poly, poly> sqrti() const;
pair<poly, poly> expi() const;
poly quo(const poly &) const;
pair<poly, poly> iquo() const;
pair<poly, poly> div(const poly &) const;
poly taylor(int k) const;
poly pow(int k) const;
poly exp(int k) const;
};
poly zeroes(int d) { return vector<int>(d + 1); }
namespace NTT {
void fft(poly &a, int lgn, int d = 1) { fft(a.base(), lgn, d); }
void fft(vector<int> &a, int lgn, int d = 1) { fft(a.data(), lgn, d); }
}
using NTT::fft;
struct SemiRelaxedConvolution {
static const int LG = 19;
static const int B = 16;
void run(int *f, const int *g, int n, const function<void(int)> &relax) {
vector<vector<int>> save(LG + 1);
function<void(int, int)> divideConquer = [&](int l, int r) {
if (r - l <= BRUTE_N2_LIMIT) {
for (int i = l + 1; i <= r; ++i) {
for (int j = l; j < i; ++j) fam(f[i], f[j], g[i - j]);
relax(i);
}
return;
}
int d = (r - l) / B + 1, lgd = 0, lg;
while ((1 << lgd) <= d * 2) ++lgd;
d = (1 << (lgd - 1)) - 1, lg = (r - l + d - 1) / d;
vector<int> dft = save[lgd];
dft.resize(lg << (lgd + 1));
for (int i = lg << lgd; i < (lg << (lgd + 1)); ++i) dft[i] = 0;
int ef = lg;
for (int i = 0; i < lg; ++i) {
if ((i << lgd) < save[lgd].size()) continue;
if ((i + 2) * d >= l) --ef;
for (int j = 0; j <= min(d * 2, n - i * d); ++j) dft[(i << lgd) + j] = g[i * d + j];
fft(dft.data() + (i << lgd), lgd);
}
for (int i = 0; i < lg; ++i) {
if (i) fft(dft.data() + ((lg + i) << lgd), lgd, -1);
for (int j = 1; j <= min(d, r - l - i * d); ++j) add(f[l + i * d + j], dft[((lg + i) << lgd) + d + j]);
divideConquer(l + i * d, min(l + (i + 1) * d, r));
if (i + 1 < lg) {
for (int j = 0; j < d; ++j) dft[((lg + i) << lgd) + j] = f[l + i * d + j];
for (int j = d; j < (1 << lgd); ++j) dft[((lg + i) << lgd) + j] = 0;
fft(dft.data() + ((lg + i) << lgd), lgd);
}
for (int j = i + 1; j < lg; ++j)
for (int k = 0; k < (1 << lgd); ++k)
fam(dft[((lg + j) << lgd) + k], dft[((j - i - 1) << lgd) + k], dft[((lg + i) << lgd) + k]);
}
};
relax(0), divideConquer(0, n);
}
} src;
poly poly::srcExp() const {
int n = deg();
poly f, g;
f.redeg(n), g.redeg(n);
for (int i = 0; i <= n; ++i) g[i] = (ll)a[i] * i % mod;
src.run(f.base(), g.base(), n, [&](int i) {
if (i == 0) f[i] = 1;
else f[i] = (ll)f[i] * ginv[i] % mod;
});
return f;
}
struct Newton {
void inv(const poly &f, const poly &dftf, poly &g, const poly &dftg, int t) {
int n = 1 << t;
poly prod = dftf;
for (int i = 0; i < (n << 1); ++i) prod[i] = (ll)prod[i] * dftg[i] % mod;
fft(prod, t + 1, -1);
memset(prod.base(), 0, sizeof(int) << t);
fft(prod, t + 1);
for (int i = 0; i < (n << 1); ++i) prod[i] = (ll)prod[i] * dftg[i] % mod;
fft(prod, t + 1, -1);
for (int i = 0; i < n; ++i) prod[i] = 0;
g -= prod;
}
void inv(const poly &f, const poly &dftf, poly &g, int t) {
poly dftg(g);
dftg.resize(2 << t);
fft(dftg, t + 1);
inv(f, dftf, g, dftg, t);
}
void inv(const poly &f, poly &g, int t) {
poly dftf(f), dftg(g);
dftf.resize(2 << t), dftg.resize(2 << t);
fft(dftf, t + 1), fft(dftg, t + 1);
inv(f, dftf, g, dftg, t);
}
void sqrt(const poly &f, poly &g, poly &dftg, poly &h, int t) {
for (int i = 0; i < (1 << t); ++i) dftg[i] = (ll)dftg[i] * dftg[i] % mod;
fft(dftg, t, -1);
dftg -= f;
for (int i = 0; i < (1 << t); ++i) add(dftg[i | (1 << t)], dftg[i]), dftg[i] = 0;
fft(dftg, t + 1);
poly tmp = h;
tmp.resize(2 << t);
fft(tmp, t + 1);
for (int i = 0; i < (2 << t); ++i) tmp[i] = (ll)tmp[i] * dftg[i] % mod;
fft(tmp, t + 1, -1);
memset(tmp.base(), 0, sizeof(int) << t);
g -= tmp * ginv[2];
}
void exp(const poly &f, poly &g, poly &dftg, poly &h, int t) {
poly dfth = h;
fft(dfth, t);
poly dg = g.deriv().slice((1 << t) - 1);
fft(dg, t);
poly tmp = zeroes((1 << t) - 1);
for (int i = 0; i < (1 << t); ++i) tmp[i] = (ll)dftg[i] * dfth[i] % mod, dg[i] = (ll)dg[i] * dfth[i] % mod;
fft(tmp, t, -1), fft(dg, t, -1);
sub(tmp[0], 1);
dg.resize(2 << t);
poly df0 = f.deriv().slice((1 << t) - 1);
df0[(1 << t) - 1] = 0;
for (int i = 0; i < (1 << t); ++i) dg[i | (1 << t)] = reduce(dg[i] - df0[i]);
memcpy(dg.base(), df0.base(), sizeof(int) * ((1 << t) - 1));
tmp.resize(2 << t), fft(tmp, t + 1);
df0.resize(2 << t), fft(df0, t + 1);
for (int i = 0; i < (2 << t); ++i) df0[i] = (ll)df0[i] * tmp[i] % mod;
fft(df0, t + 1, -1);
for (int i = 0; i < (1 << t); ++i) df0[i | (1 << t)] = df0[i], df0[i] = 0;
dg = (dg - df0).integ().slice((2 << t) - 1) - f;
fft(dg, t + 1);
for (int i = 0; i < (2 << t); ++i) tmp[i] = (ll)dg[i] * dftg[i] % mod;
fft(tmp, t + 1, -1);
g.resize(2 << t);
for (int i = 1 << t; i < (2 << t); ++i) g[i] = neg(tmp[i]);
}
} nit;
struct Transposition {
vector<int> _mul(int l, vector<int> res, const poly &b) {
vector<int> tmp(1 << l);
memcpy(tmp.data(), b.base(), sizeof(int) * (b.deg() + 1));
reverse(tmp.begin() + 1, tmp.end());
fft(tmp.data(), l);
for (int i = 0; i < (1 << l); ++i) res[i] = (ll)res[i] * tmp[i] % mod;
fft(res.data(), l, -1);
return res;
}
poly bfMul(const poly &a, const poly &b) {
int n = a.deg(), m = b.deg();
poly ret = zeroes(n - m);
for (int i = 0; i <= n - m; ++i)
for (int j = 0; j <= m; ++j) ret[i] = (ret[i] + (ll)a[i + j] * b[j]) % mod;
return ret;
}
poly mul(const poly &a, const poly &b) {
if (a.deg() < b.deg()) return 0;
if (a.deg() <= BRUTE_N2_LIMIT) return bfMul(a, b);
int l = 0;
while ((1 << l) <= a.deg()) ++l;
vector<int> res(1 << l);
memcpy(res.data(), a.base(), sizeof(int) * (a.deg() + 1));
fft(res.data(), l);
res = _mul(l, res, b);
res.resize(a.deg() - b.deg() + 1);
return res;
}
pair<poly, poly> mul2(const poly &a, const poly &b1, const poly &b2) {
if (a.deg() <= BRUTE_N2_LIMIT) return make_pair(bfMul(a, b1), bfMul(a, b2));
int l = 0;
while ((1 << l) <= a.deg()) ++l;
vector<int> fa(1 << l);
memcpy(fa.data(), a.base(), sizeof(int) * (a.deg() + 1));
fft(fa.data(), l);
vector<int> res1 = _mul(l, fa, b1), res2 = _mul(l, fa, b2);
res1.resize(a.deg() - b1.deg() + 1), res2.resize(a.deg() - b2.deg() + 1);
return {res1, res2};
}
vector<int> ls, rs, pos;
vector<poly> p, q;
void _build(int n) {
ls.assign(n * 2 - 1, 0), rs.assign(n * 2 - 1, 0), p.assign(n * 2 - 1, 0), q.assign(n * 2 - 1, 0), pos.resize(n);
int cnt = 0;
function<int(int, int)> dfs = [&](int l, int r) {
if (l == r) { pos[l] = cnt; return cnt++; }
int ret = cnt++;
int mid = (l + r) >> 1;
ls[ret] = dfs(l, mid), rs[ret] = dfs(mid + 1, r);
return ret;
};
dfs(0, n - 1);
}
vector<int> _eval(vector<int> f, const vector<int> &x) {
int n = f.size();
_build(n);
for (int i = 0; i < n; ++i) q[pos[i]] = {1, neg(x[i])};
for (int i = n * 2 - 2; i >= 0; --i)
if (ls[i]) q[i] = q[ls[i]] * q[rs[i]];
f.resize(n * 2);
p[0] = mul(f, q[0].inv());
for (int i = 0; i < n * 2 - 1; ++i)
if (ls[i]) tie(p[ls[i]], p[rs[i]]) = mul2(p[i], q[rs[i]], q[ls[i]]);
vector<int> ret(n);
for (int i = 0; i < n; ++i) ret[i] = p[pos[i]][0];
return ret;
}
vector<int> eval(const poly &f, const vector<int> &x) {
int n = f.deg() + 1, m = x.size();
vector<int> tmpf = f.a, tmpx = x;
tmpf.resize(max(n, m)), tmpx.resize(max(n, m));
vector<int> ret = _eval(tmpf, tmpx);
ret.resize(m);
return ret;
}
poly inter(const vector<int> &x, const vector<int> &y) {
int n = x.size();
_build(n);
for (int i = 0; i < n; ++i) q[pos[i]] = {1, norm(mod - x[i])};
for (int i = n * 2 - 2; i >= 0; --i)
if (ls[i]) q[i] = q[ls[i]] * q[rs[i]];
poly tmp = q[0];
reverse(tmp.a.begin(), tmp.a.end());
vector<int> f = tmp.deriv().a;
f.resize(n * 2);
p[0] = mul(f, q[0].inv());
for (int i = 0; i < n * 2 - 1; ++i)
if (ls[i]) tie(p[ls[i]], p[rs[i]]) = mul2(p[i], q[rs[i]], q[ls[i]]);
for (int i = 0; i < n; ++i) p[pos[i]] = nt.inv(p[pos[i]][0]) * (ll)y[i] % mod;
for (int i = 0; i < n * 2 - 1; ++i) reverse(q[i].a.begin(), q[i].a.end());
for (int i = n * 2 - 2; i >= 0; --i)
if (ls[i]) p[i] = p[ls[i]] * q[rs[i]] + p[rs[i]] * q[ls[i]];
return p[0];
}
} tp;
struct FactorialPolynomials {
pair<poly, poly> mul2(const poly &a, const poly &b1, const poly &b2) {
int n = a.deg() + max(b1.deg(), b2.deg());
if (n <= BRUTE_N2_LIMIT) return {a * b1, a * b2};
int l = 0;
while ((1 << l) <= n) ++l;
vector<int> fa(1 << l);
memcpy(fa.data(), a.base(), sizeof(int) * (a.deg() + 1));
fft(fa.data(), l);
vector<int> res1(1 << l), res2(1 << l);
memcpy(res1.data(), b1.base(), sizeof(int) * (b1.deg() + 1)), memcpy(res2.data(), b2.base(), sizeof(int) * (b2.deg() + 1));
fft(res1.data(), l), fft(res2.data(), l);
for (int i = 0; i < (1 << l); ++i) res1[i] = (ll)res1[i] * fa[i] % mod, res2[i] = (ll)res2[i] * fa[i] % mod;
fft(res1.data(), l, -1), fft(res2.data(), l, -1);
res1.resize(a.deg() + b1.deg() + 1), res2.resize(a.deg() + b2.deg() + 1);
return {res1, res2};
}
vector<int> ls, rs, pos;
vector<poly> p, q;
void _build(int n) {
ls.assign(n * 2 - 1, 0), rs.assign(n * 2 - 1, 0), p.assign(n * 2 - 1, 0), q.assign(n * 2 - 1, 0), pos.resize(n);
int cnt = 0;
function<int(int, int)> dfs = [&](int l, int r) {
if (l == r) { pos[l] = cnt; return cnt++; }
int ret = cnt++;
int mid = (l + r) >> 1;
ls[ret] = dfs(l, mid), rs[ret] = dfs(mid + 1, r);
return ret;
};
dfs(0, n - 1);
}
vector<int> toPoly(vector<int> f) {
int n = f.size();
_build(n);
for (int i = 0; i < n; ++i) p[pos[i]] = f[i], q[pos[i]] = {neg(i), 1};
for (int i = n * 2 - 2; i >= 0; --i)
if (ls[i]) tie(p[i], q[i]) = mul2(q[ls[i]], p[rs[i]], q[rs[i]]), p[i] += p[ls[i]];
return p[0];
}
vector<int> lagrange(int x, vector<int> y) {
int m = y.size(), n = m * 2 - 1;
vector<int> tinv(n);
if (x == m)
for (int i = 0; i < n; ++i) tinv[i] = ginv[x - (m - 1 - i)];
else {
vector<int> tfac(n), tifac(n);
tfac[0] = reduce(x - (m - 1));
for (int i = 1; i < n; ++i) tfac[i] = (ll)tfac[i - 1] * (x - (m - 1 - i) + mod) % mod;
tifac[n - 1] = nt.inv(tfac[n - 1]);
for (int i = n - 1; i; --i) tifac[i - 1] = (ll)tifac[i] * (x - (m - 1 - i) + mod) % mod;
tinv[0] = tifac[0];
for (int i = 1; i < n; ++i) tinv[i] = (ll)tifac[i] * tfac[i - 1] % mod;
}
for (int i = 0; i < m; ++i)
y[i] = (ll)((m - i) & 1 ? y[i] : mod - y[i]) * gifac[i] % mod * gifac[m - 1 - i] % mod;
vector<int> ret(m);
if (n <= BRUTE_N2_LIMIT) {
for (int i = 0; i < m; ++i)
for (int j = 0; j <= m - 1 + i && j < m; ++j)
fam(ret[i], y[j], tinv[m - 1 + i - j]);
} else {
int l = 0;
while ((1 << l) < n) ++l;
auto tmp = tinv;
y.resize(1 << l), tmp.resize(1 << l);
fft(y.data(), l), fft(tmp.data(), l);
for (int i = 0; i < (1 << l); ++i) tmp[i] = (ll)tmp[i] * y[i] % mod;
fft(tmp.data(), l, -1);
memcpy(ret.data(), tmp.data() + m - 1, sizeof(int) * m);
}
int fac = 1;
for (int i = 0; i < m; ++i) fac = (ll)fac * (x - i) % mod;
for (int i = 0; i < m; ++i)
ret[i] = (ll)ret[i] * fac % mod,
fac = (ll)fac * (x + i + 1) % mod * tinv[i] % mod;
return ret;
}
pair<vector<int>, vector<int>> lagrange2(int x, vector<int> y1, vector<int> y2) {
assert(y1.size() == y2.size());
int m = y1.size(), n = m * 2 - 1;
vector<int> tinv(n);
if (x == m)
for (int i = 0; i < n; ++i) tinv[i] = ginv[x - (m - 1 - i)];
else {
vector<int> tfac(n), tifac(n);
tfac[0] = reduce(x - (m - 1));
for (int i = 1; i < n; ++i) tfac[i] = (ll)tfac[i - 1] * (x - (m - 1 - i) + mod) % mod;
tifac[n - 1] = nt.inv(tfac[n - 1]);
for (int i = n - 1; i; --i) tifac[i - 1] = (ll)tifac[i] * (x - (m - 1 - i) + mod) % mod;
tinv[0] = tifac[0];
for (int i = 1; i < n; ++i) tinv[i] = (ll)tifac[i] * tfac[i - 1] % mod;
}
for (int i = 0; i < m; ++i)
y1[i] = (ll)((m - i) & 1 ? y1[i] : mod - y1[i]) * gifac[i] % mod * gifac[m - 1 - i] % mod,
y2[i] = (ll)((m - i) & 1 ? y2[i] : mod - y2[i]) * gifac[i] % mod * gifac[m - 1 - i] % mod;
vector<int> ret1(m), ret2(m);
if (n <= BRUTE_N2_LIMIT) {
for (int i = 0; i < m; ++i)
for (int j = 0; j <= m - 1 + i && j < m; ++j)
fam(ret1[i], y1[j], tinv[m - 1 + i - j]),
fam(ret2[i], y2[j], tinv[m - 1 + i - j]);
} else {
int l = 0;
while ((1 << l) < n) ++l;
auto tmp = tinv;
y1.resize(1 << l), y2.resize(1 << l), tmp.resize(1 << l);
fft(y1.data(), l), fft(y2.data(), l), fft(tmp.data(), l);
for (int i = 0; i < (1 << l); ++i)
y1[i] = (ll)tmp[i] * y1[i] % mod, y2[i] = (ll)tmp[i] * y2[i] % mod;
fft(y1.data(), l, -1), fft(y2.data(), l, -1);
memcpy(ret1.data(), y1.data() + m - 1, sizeof(int) * m),
memcpy(ret2.data(), y2.data() + m - 1, sizeof(int) * m);
}
int fac = 1;
for (int i = 0; i < m; ++i) fac = (ll)fac * (x - i) % mod;
for (int i = 0; i < m; ++i)
ret1[i] = (ll)ret1[i] * fac % mod, ret2[i] = (ll)ret2[i] * fac % mod,
fac = (ll)fac * (x + i + 1) % mod * tinv[i] % mod;
return {ret1, ret2};
}
vector<int> lagrangeDoubling(vector<int> f) {
auto tmp = lagrange(f.size(), f);
f.insert(f.end(), tmp.begin(), tmp.end());
return f;
}
pair<vector<int>, vector<int>> lagrangeDoubling2(vector<int> f1, vector<int> f2) {
vector<int> tmp1, tmp2;
tie(tmp1, tmp2) = lagrange2(f1.size(), f1, f2);
f1.insert(f1.end(), tmp1.begin(), tmp1.end()),
f2.insert(f2.end(), tmp2.begin(), tmp2.end());
return {f1, f2};
}
vector<int> lagrangeExtending(vector<int> f) {
int n = f.size();
int res = 0;
for (int i = 0; i < n; ++i)
res = (res + (ll)((n - i) & 1 ? f[i] : mod - f[i]) * gifac[i] % mod * gifac[n - 1 - i] % mod * ginv[n - i]) % mod;
for (int i = 1; i <= n; ++i) res = (ll)res * i % mod;
f.push_back(res);
return f;
}
vector<int> evalFacPoly(vector<int> f) {
int n = f.size();
poly g = zeroes(n - 1);
for (int i = 0; i < n; ++i) g[i] = gifac[i];
g = (g * f).slice(n - 1);
for (int i = 0; i < n; ++i) g[i] = (ll)g[i] * gfac[i] % mod;
return g;
}
vector<int> evalPoly(vector<int> f) {
int n = f.size();
_build(n);
for (int i = 0; i < n; ++i) p[pos[i]] = f[i];
for (int i = n * 2 - 2; i >= 0; --i)
if (ls[i]) {
vector<int> l = p[ls[i]], r = p[rs[i]];
if (l.size() > r.size())
tie(l, r) = lagrangeDoubling2(l, lagrangeExtending(r)),
l.pop_back(), r.pop_back();
else tie(l, r) = lagrangeDoubling2(l, r);
p[i].resize(p[ls[i]].size() + p[rs[i]].size());
for (int j = 0; j < p[i].size(); ++j)
p[i][j] = (l[j] + (ll)r[j] * mpow(j, p[ls[i]].size())) % mod;
}
return p[0];
}
vector<int> interFacPoly(vector<int> y) {
int n = y.size();
poly g = zeroes(n - 1);
for (int i = 0; i < n; ++i)
g[i] = i & 1 ? mod - gifac[i] : gifac[i], y[i] = (ll)y[i] * gifac[i] % mod;
return (g * y).slice(n - 1);
}
vector<int> interPoly(vector<int> y) { return toPoly(interFacPoly(y)); }
vector<int> toFacPoly(vector<int> f) { return interFacPoly(evalPoly(f)); }
vector<int> mul(vector<int> a, vector<int> b) {
int n = a.size() + b.size() - 1;
a.resize(n), b.resize(n);
a = evalFacPoly(a), b = evalFacPoly(b);
for (int i = 0; i < n; ++i) a[i] = (ll)a[i] * b[i] % mod;
return interFacPoly(a);
}
} fp;
poly poly::operator*(const poly &o) const {
int n = deg(), m = o.deg();
if (0 && (n <= 10 || m <= 10 || n + m <= BRUTE_N2_LIMIT)) {
poly ret = zeroes(n + m);
for (int i = 0; i <= n; ++i)
for (int j = 0; j <= m; ++j) fam(ret[i + j], a[i], o[j]);
return ret;
}
n += m;
int l = 0;
while ((1 << l) <= n) ++l;
poly ret = a, tmp = o;
ret.resize(1 << l), tmp.resize(1 << l);
fft(ret, l), fft(tmp, l);
for (int i = 0; i < (1 << l); ++i) ret[i] = (ll)ret[i] * tmp[i] % mod;
fft(ret, l, -1);
return ret.slice(n);
}
poly poly::inv() const {
poly g = nt.inv(a[0]);
for (int t = 0; (1 << t) <= deg(); ++t) nit.inv(slice((2 << t) - 1), g, t);
g.redeg(deg());
return g;
}
poly poly::taylor(int k) const {
int n = deg();
poly f = zeroes(n), g = zeroes(n);
for (int i = 0, pw = 1; i <= n; ++i)
f[n - i] = (ll)a[i] * gfac[i] % mod, g[i] = (ll)pw * gifac[i] % mod, pw = (ll)pw * k % mod;
f *= g;
for (int i = 0; i <= n; ++i) g[i] = (ll)f[n - i] * gifac[i] % mod;
return g;
}
poly poly::pow(int k) const {
if (k == 0) return 1;
if (k == 1) return *this;
int n = deg() * k;
int l = 0;
while ((1 << l) <= n) ++l;
poly ret = a;
ret.resize(1 << l), fft(ret, l);
for (int i = 0; i < (1 << l); ++i) ret[i] = mpow(ret[i], k);
fft(ret, -1);
return ret.slice(n);
}
poly poly::deriv() const {
if (deg() == 0) return 0;
vector<int> ret(deg());
for (int i = 0; i < deg(); ++i) ret[i] = (ll)a[i + 1] * (i + 1) % mod;
return ret;
}
poly poly::integ() const {
vector<int> ret(size() + 1);
for (int i = 0; i <= deg(); ++i) ret[i + 1] = (ll)a[i] * ginv[i + 1] % mod;
return ret;
}
poly poly::quo(const poly &o) const {
if (o.deg() == 0) return (ll)a[0] * nt.inv(o[0]) % mod;
poly g = nt.inv(o[0]);
int t = 0, n;
for (n = 1; (n << 1) <= o.deg(); ++t, n <<= 1) nit.inv(o.slice((n << 1) - 1), g, t);
poly dftg = g;
dftg.resize(n << 1), fft(dftg, t + 1);
poly eps1 = o;
eps1.resize(n << 1), fft(eps1, t + 1);
for (int i = 0; i < (n << 1); ++i) eps1[i] = (ll)eps1[i] * dftg[i] % mod;
fft(eps1, t + 1, -1);
for (int i = 0; i < n; ++i) eps1[i] = eps1[i + n], eps1[i + n] = 0;
fft(eps1, t + 1);
poly h0 = slice(n - 1);
h0.resize(n << 1), fft(h0, t + 1);
poly h0g0 = zeroes((n << 1) - 1);
for (int i = 0; i < (n << 1); ++i) h0g0[i] = (ll)h0[i] * dftg[i] % mod;
fft(h0g0, t + 1, -1);
poly h0eps1 = zeroes((n << 1) - 1);
for (int i = 0; i < (n << 1); ++i) h0eps1[i] = (ll)h0[i] * eps1[i] % mod;
fft(h0eps1, t + 1, -1);
for (int i = 0; i < n; ++i) h0eps1[i] = reduce(operator[](i + n) - h0eps1[i]);
memset(h0eps1.base() + n, 0, sizeof(int) << t);
fft(h0eps1, t + 1);
for (int i = 0; i < (n << 1); ++i) h0eps1[i] = (ll)h0eps1[i] * dftg[i] % mod;
fft(h0eps1, t + 1, -1);
for (int i = 0; i < n; ++i) h0eps1[i + n] = h0eps1[i], h0eps1[i] = 0;
return (h0g0 + h0eps1).slice(o.deg());
}
poly poly::ln() const {
if (deg() == 0) return 0;
return deriv().quo(slice(deg() - 1)).integ();
}
pair<poly, poly> poly::sqrti() const {
poly g = nt.sqrt(a[0]), h = nt.inv(a[0]), dftg = g;
for (int t = 0; (1 << t) <= deg(); ++t) {
nit.sqrt(slice((2 << t) - 1), g, dftg, h, t);
dftg = g, fft(dftg, t + 1);
nit.inv(g, dftg, h, t);
}
return make_pair(g.slice(deg()), h.slice(deg()));
}
poly poly::sqrt() const {
poly g = nt.sqrt(a[0]), h = nt.inv(a[0]), dftg = g;
for (int t = 0; (1 << t) <= deg(); ++t) {
nit.sqrt(slice((2 << t) - 1), g, dftg, h, t);
if ((2 << t) <= deg()) {
dftg = g, fft(dftg, t + 1);
nit.inv(g, dftg, h, t);
}
}
return g.slice(deg());
}
pair<poly, poly> poly::expi() const {
poly g = 1, h = 1, dftg = {1, 1};
for (int t = 0; (1 << t) <= deg(); ++t) {
nit.exp(slice((2 << t) - 1), g, dftg, h, t);
dftg = g, dftg.resize(4 << t);
fft(dftg, t + 2);
poly f2n = dftg.slice((2 << t) - 1);
nit.inv(g, f2n, h, t);
}
return make_pair(g.slice(deg()), h.slice(deg()));
}
poly poly::exp() const {
poly g = 1, h = 1, dftg = {1, 1};
for (int t = 0; (1 << t) <= deg(); ++t) {
nit.exp(slice((2 << t) - 1), g, dftg, h, t);
if ((2 << t) <= deg()) {
dftg = g, dftg.resize(4 << t);
fft(dftg, t + 2);
poly f2n = dftg.slice((2 << t) - 1);
nit.inv(g, f2n, h, t);
}
}
return g.slice(deg());
}
poly poly::exp(int k) const {
int lead, lz = 0;
while (lz < deg() && !a[lz]) ++lz;
if (lz == deg() && !a[lz]) return *this;
lead = a[lz];
if ((ll)lz * k > deg()) return zeroes(deg());
poly part = poly(vector<int>(a.begin() + lz, a.begin() + deg() - lz * (k - 1) + 1)) * nt.inv(lead);
part = (part.ln() * k).srcExp() * mpow(lead, k);
vector<int> ret(deg() + 1);
memcpy(ret.data() + lz * k, part.base(), sizeof(int) * (deg() - lz * k + 1));
return ret;
}
poly poly::operator/(const poly &o) const {
int n = deg(), m = o.deg();
if (n < m) return 0;
poly ta(vector<int>(a.rbegin(), a.rend())), tb(vector<int>(o.a.rbegin(), o.a.rend()));
ta.redeg(n - m), tb.redeg(n - m);
poly q = ta.quo(tb);
return vector<int>(q.a.rbegin(), q.a.rend());
}
pair<poly, poly> poly::div(const poly &o) const {
if (deg() < o.deg()) return make_pair(0, *this);
int n = deg(), m = o.deg();
poly q = operator/(o), r;
int l = 0;
while ((1 << l) < o.deg()) ++l;
int t = (1 << l) - 1;
poly tmp = zeroes(t);
r = zeroes(t);
for (int i = 0; i <= m; ++i) add(r[i & t], o[i]);
for (int i = 0; i <= n - m; ++i) add(tmp[i & t], q[i]);
fft(r, l), fft(tmp, l);
for (int i = 0; i <= t; ++i) tmp[i] = (ll)tmp[i] * r[i] % mod;
fft(tmp, l, -1);
memset(r.base(), 0, sizeof(int) << l);
for (int i = 0; i <= n; ++i) add(r[i & t], a[i]);
for (int i = 0; i < m; ++i) sub(r[i], tmp[i]);
return make_pair(q, r.slice(m - 1));
}
poly poly::operator%(const poly &o) const { return div(o).second; }
const int N = 2e5;
int alpha, n, m;
int n0, m0;
poly f, h;
int g[N + 5], df[N + 5], dg[N + 5];
struct RelaxedConvolution {
static const int LG = 19;
static const int B = 16;
void run(int *f, int *g, int *df, int *dg, int n, const function<void(int)> &relax) {
vector<vector<int>> savef(LG + 1), saveg(LG + 1), savedf(LG + 1), savedg(LG + 1);
function<void(int, int)> divideConquer = [&](int l, int r) {
if (r - l <= BRUTE_N2_LIMIT) {
for (int i = l + 1; i <= r; ++i) {
for (int j = l; j < i; ++j)
g[i] = (g[i] + (ll)df[j] * g[i - j] + (ll)dg[j] * f[i - j]) % mod,
f[i] = (f[i] + (ll)f[j] * g[i - j]) % mod;
if (l > 0)
for (int j = l; j < i; ++j)
g[i] = (g[i] + (ll)g[j] * df[i - j] + (ll)f[j] * dg[i - j]) % mod,
f[i] = (f[i] + (ll)g[j] * f[i - j]) % mod;
relax(i);
}
return ;
}
if (l == 0) {
int mid = ((l + r) >> 1) + 5;
divideConquer(l, mid);
int lgd = 0;
for (; (1 << lgd) <= r; ++lgd);
vector<int> tf(1 << lgd), tg(1 << lgd), tdf(1 << lgd), tdg(1 << lgd);
for (int i = 0; i < mid; ++i) tf[i] = f[i], tg[i] = g[i], tdf[i] = df[i], tdg[i] = dg[i];
fft(tf, lgd), fft(tg, lgd), fft(tdf, lgd), fft(tdg, lgd);
for (int i = 0; i < (1 << lgd); ++i) {
int tmp = tf[i];
tf[i] = (ll)tf[i] * tg[i] % mod,
tg[i] = ((ll)tmp * tdg[i] + (ll)tg[i] * tdf[i]) % mod;
}
fft(tf, lgd, -1), fft(tg, lgd, -1);
for (int i = mid + 1; i <= r; ++i) add(f[i], tf[i]), add(g[i], tg[i]);
divideConquer(mid, r);
return ;
}
int d = (r - l) / B + 1, lgd = 0, lg;
for (; (1 << lgd) <= d * 2; ++lgd);
d = (1 << (lgd - 1)) - 1, lg = (r - l + d - 1) / d;
auto dftf = savef[lgd], dftg = saveg[lgd], dftdf = savedf[lgd], dftdg = savedg[lgd];
dftf.resize(lg << (lgd + 1)), dftg.resize(lg << (lgd + 1)),
dftdf.resize(lg << (lgd + 1)), dftdg.resize(lg << (lgd + 1));
for (int i = lg << lgd; i < (lg << (lgd + 1)); ++i) dftf[i] = dftg[i] = dftdf[i] = dftdg[i] = 0;
int ef = lg;
for (int i = 0; i < lg; ++i) {
if ((i << lgd) < savef[lgd].size()) continue;
if ((i + 2) * d >= l) --ef;
for (int j = 0; j <= min(d * 2, n - i * d); ++j)
dftf[(i << lgd) + j] = f[i * d + j],
dftg[(i << lgd) + j] = g[i * d + j],
dftdf[(i << lgd) + j] = df[i * d + j],
dftdg[(i << lgd) + j] = dg[i * d + j];
fft(dftf.data() + (i << lgd), lgd), fft(dftg.data() + (i << lgd), lgd),
fft(dftdf.data() + (i << lgd), lgd), fft(dftdg.data() + (i << lgd), lgd);
}
if (savef[lgd].size() < (ef << lgd)) {
savef[lgd] = vector<int>(dftf.begin(), dftf.begin() + (ef << lgd)),
saveg[lgd] = vector<int>(dftg.begin(), dftg.begin() + (ef << lgd)),
savedf[lgd] = vector<int>(dftdf.begin(), dftdf.begin() + (ef << lgd)),
savedg[lgd] = vector<int>(dftdg.begin(), dftdg.begin() + (ef << lgd));
}
for (int i = 0; i < lg; ++i) {
if (i)
fft(dftf.data() + ((lg + i) << lgd), lgd, -1), fft(dftg.data() + ((lg + i) << lgd), lgd, -1);
for (int j = 1; j <= min(d, r - l - i * d); ++j)
add(f[l + i * d + j], dftf[((lg + i) << lgd) + d + j]),
add(g[l + i * d + j], dftg[((lg + i) << lgd) + d + j]);
divideConquer(l + i * d, min(l + (i + 1) * d, r));
if (i + 1 < lg) {
for (int j = 0; j < d; ++j)
dftf[((lg + i) << lgd) + j] = f[l + i * d + j],
dftg[((lg + i) << lgd) + j] = g[l + i * d + j],
dftdf[((lg + i) << lgd) + j] = df[l + i * d + j],
dftdg[((lg + i) << lgd) + j] = dg[l + i * d + j];
for (int j = d; j < (1 << lgd); ++j) dftf[((lg + i) << lgd) + j] = dftg[((lg + i) << lgd) + j] = 0;
fft(dftf.data() + ((lg + i) << lgd), lgd), fft(dftg.data() + ((lg + i) << lgd), lgd),
fft(dftdf.data() + ((lg + i) << lgd), lgd), fft(dftdg.data() + ((lg + i) << lgd), lgd);
}
for (int j = i + 1; j < lg; ++j)
for (int k = 0; k < (1 << lgd); ++k)
dftf[((lg + j) << lgd) + k] = (dftf[((lg + j) << lgd) + k] +
(ll)dftf[((j - i - 1) << lgd) + k] * dftg[((lg + i) << lgd) + k] +
(ll)dftg[((j - i - 1) << lgd) + k] * dftf[((lg + i) << lgd) + k]
) % mod,
dftg[((lg + j) << lgd) + k] = (dftg[((lg + j) << lgd) + k] +
(ll)dftdf[((j - i - 1) << lgd) + k] * dftg[((lg + i) << lgd) + k] +
(ll)dftg[((j - i - 1) << lgd) + k] * dftdf[((lg + i) << lgd) + k] +
(ll)dftdg[((j - i - 1) << lgd) + k] * dftf[((lg + i) << lgd) + k] +
(ll)dftf[((j - i - 1) << lgd) + k] * dftdg[((lg + i) << lgd) + k]
) % mod;
}
};
relax(0), divideConquer(0, n);
}
} rc;
int main() {
scanf("%d%d%d%d", &alpha, &n, &m, &n0);
for (int i = 1, las = 0; i <= n0 * alpha; ++i) {
int x; scanf("%d", &x);
m0 += las > x, las = x;
}
f.redeg(m + 1), rc.run(f.base(), g, df, dg, m + 1, [&](int k) {
if (k == 0) f[k] = 0, g[k] = 1;
else if (k == 1) f[k] = 1, g[k] = alpha - 1;
else
f[k] = (ll)f[k] * ginv[k - 1] % mod,
g[k] = ((ll)(alpha - 1) * f[k] + (ll)g[k] * ginv[k]) % mod;
df[k] = (ll)(alpha - 1) * k % mod * f[k] % mod,
dg[k] = (ll)k * g[k] % mod;
});
h = (f.exp(m0 + 1) * (-f + 1).exp(mod - alpha * n0 - 1)).slice(m + 1);
for (int i = 0; i <= m + 1; ++i) h[i] = (ll)mpow(i, n - n0) * h[i] % mod;
poly p = (h * (-f + 1).exp(((ll)alpha * n + 1) % mod)).slice(m + 1).deriv(), q = f.shift(-1).exp(mod - m - 1);
int ans = 0;
for (int i = 0; i <= m; ++i) ans = (ans + (ll)p[i] * q[m - i]) % mod;
ans = (ll)ans * ginv[m + 1] % mod;
printf("%d\n", ans);
}
这程序好像有点Bug,我给组数据试试?
詳細信息
Subtask #1:
score: 10
Accepted
Test #1:
score: 10
Accepted
time: 8ms
memory: 6132kb
input:
584 1985 1017 186 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...
output:
683567838
result:
ok 1 number(s): "683567838"
Test #2:
score: 10
Accepted
time: 4ms
memory: 6252kb
input:
549 1352 215 144 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1...
output:
514220824
result:
ok 1 number(s): "514220824"
Test #3:
score: 10
Accepted
time: 7ms
memory: 6136kb
input:
280 1833 1153 253 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 ...
output:
801426026
result:
ok 1 number(s): "801426026"
Test #4:
score: 10
Accepted
time: 10ms
memory: 4184kb
input:
886 1885 1736 131 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 ...
output:
732050911
result:
ok 1 number(s): "732050911"
Test #5:
score: 10
Accepted
time: 13ms
memory: 4192kb
input:
464 1859 1766 385 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 150 150 150 150 150 150 150 150 150 150 150 150 150 150 150...
output:
268474724
result:
ok 1 number(s): "268474724"
Test #6:
score: 10
Accepted
time: 9ms
memory: 6016kb
input:
468 1281 718 285 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1...
output:
7958328
result:
ok 1 number(s): "7958328"
Test #7:
score: 10
Accepted
time: 5ms
memory: 5988kb
input:
973 1966 417 99 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 ...
output:
943626008
result:
ok 1 number(s): "943626008"
Test #8:
score: 10
Accepted
time: 8ms
memory: 4420kb
input:
224 1781 1724 358 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 ...
output:
550100613
result:
ok 1 number(s): "550100613"
Test #9:
score: 10
Accepted
time: 4ms
memory: 6048kb
input:
952 1793 939 19 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1...
output:
357850463
result:
ok 1 number(s): "357850463"
Test #10:
score: 10
Accepted
time: 4ms
memory: 6308kb
input:
978 1415 776 108 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1...
output:
284767772
result:
ok 1 number(s): "284767772"
Subtask #2:
score: 10
Accepted
Test #11:
score: 10
Accepted
time: 470ms
memory: 17652kb
input:
1 199913 100055 1 1
output:
856065368
result:
ok 1 number(s): "856065368"
Test #12:
score: 10
Accepted
time: 881ms
memory: 25144kb
input:
1 197151 139288 1 1
output:
933745116
result:
ok 1 number(s): "933745116"
Test #13:
score: 10
Accepted
time: 529ms
memory: 18480kb
input:
1 198165 124475 1 1
output:
650379731
result:
ok 1 number(s): "650379731"
Test #14:
score: 10
Accepted
time: 1003ms
memory: 27868kb
input:
1 199407 183908 1 1
output:
213038974
result:
ok 1 number(s): "213038974"
Test #15:
score: 10
Accepted
time: 403ms
memory: 13464kb
input:
1 195940 66608 1 1
output:
203000250
result:
ok 1 number(s): "203000250"
Subtask #3:
score: 30
Accepted
Dependency #2:
100%
Accepted
Test #16:
score: 30
Accepted
time: 472ms
memory: 17816kb
input:
1 199968 100029 81 1 2 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
output:
882662058
result:
ok 1 number(s): "882662058"
Test #17:
score: 30
Accepted
time: 928ms
memory: 25884kb
input:
1 199237 160399 740 534 70 635 736 56 408 68 506 354 47 101 96 66 699 497 89 642 133 179 211 318 261 205 321 300 363 165 643 236 21 176 212 232 702 195 687 14 382 207 216 149 374 222 438 50 256 427 79 38 147 215 605 678 46 645 610 538 118 22 11 548 194 628 590 375 26 180 591 264 366 226 185 188 406 ...
output:
119843424
result:
ok 1 number(s): "119843424"
Test #18:
score: 30
Accepted
time: 995ms
memory: 27832kb
input:
1 197117 182307 1145 649 641 894 352 882 609 560 160 360 183 542 220 1059 750 489 977 810 964 48 812 540 346 210 345 284 969 371 274 978 1083 282 986 632 484 889 768 533 226 922 58 870 888 63 850 321 548 471 212 643 233 1109 994 1090 1145 979 405 418 555 394 781 1000 709 819 652 1117 703 397 715 102...
output:
321584073
result:
ok 1 number(s): "321584073"
Test #19:
score: 30
Accepted
time: 1011ms
memory: 28884kb
input:
1 198080 196910 32807 13007 28354 16100 16920 19352 19610 14746 9160 6498 3691 32453 7386 16081 16509 7087 30770 27569 32126 31416 15799 12675 25754 20433 93 21896 24361 20050 15789 1724 5623 25658 31528 30773 30698 21920 5237 2778 29667 25560 237 8327 892 12072 9109 30004 22873 24074 29546 25501 26...
output:
0
result:
ok 1 number(s): "0"
Test #20:
score: 30
Accepted
time: 538ms
memory: 19160kb
input:
1 198858 125784 938 257 251 742 779 56 449 69 7 370 454 811 343 831 233 532 626 253 216 398 675 851 677 690 705 34 414 28 309 685 102 786 835 67 351 612 357 399 530 859 130 732 540 275 467 469 311 642 664 574 802 581 20 42 916 52 375 124 154 572 342 730 231 134 692 561 431 452 30 747 302 723 367 386...
output:
568776181
result:
ok 1 number(s): "568776181"
Subtask #4:
score: 15
Accepted
Test #21:
score: 15
Accepted
time: 466ms
memory: 16280kb
input:
2 199984 99989 1 1 1
output:
169573504
result:
ok 1 number(s): "169573504"
Test #22:
score: 15
Accepted
time: 962ms
memory: 26796kb
input:
2 198253 176846 1 1 1
output:
206376024
result:
ok 1 number(s): "206376024"
Test #23:
score: 15
Accepted
time: 541ms
memory: 19180kb
input:
2 197635 128767 1 1 1
output:
517345888
result:
ok 1 number(s): "517345888"
Test #24:
score: 15
Accepted
time: 886ms
memory: 23692kb
input:
2 198367 139324 1 1 1
output:
421558104
result:
ok 1 number(s): "421558104"
Test #25:
score: 15
Accepted
time: 979ms
memory: 26632kb
input:
2 197383 177188 1 1 1
output:
47912879
result:
ok 1 number(s): "47912879"
Subtask #5:
score: 15
Accepted
Dependency #4:
100%
Accepted
Test #26:
score: 15
Accepted
time: 483ms
memory: 17564kb
input:
2 199972 99897 63 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 21 21 22 22 23 23 24 24 25 25 26 26 27 27 28 28 29 29 30 30 31 31 32 32 33 33 34 34 35 35 36 36 37 37 38 38 39 39 40 40 41 41 42 42 43 43 44 44 45 45 46 46 47 47 48 48 49 49 50 50 ...
output:
646686125
result:
ok 1 number(s): "646686125"
Test #27:
score: 15
Accepted
time: 931ms
memory: 24528kb
input:
2 198230 150849 8875 2376 5489 5489 2376 3711 3711 5679 5679 4601 5973 5973 4601 554 4256 4596 4596 4256 554 4800 6366 6366 4800 2879 5348 5348 2879 1693 4230 6262 6993 8595 8595 6993 6262 4230 1693 2663 3954 3954 2663 14 14 7910 7910 4020 4020 3246 6907 6907 3246 8873 8873 4762 4762 520 520 1366 54...
output:
321924755
result:
ok 1 number(s): "321924755"
Test #28:
score: 15
Accepted
time: 831ms
memory: 25624kb
input:
2 199806 150052 89583 49845 49845 25156 25156 5539 20884 20884 5539 58128 84993 84993 58128 2142 47997 47997 65672 65672 22214 22214 10670 39754 74544 74544 48064 48064 39754 10670 7926 74018 74018 7926 33809 33809 14019 14019 38860 38860 2142 3555 71750 71750 26496 32708 32708 56732 56732 82049 820...
output:
160305146
result:
ok 1 number(s): "160305146"
Test #29:
score: 15
Accepted
time: 531ms
memory: 18316kb
input:
2 199723 124579 36954 26124 26124 18080 18080 7015 13358 13358 7015 300 15945 18773 18773 30036 30036 33473 33473 15945 2386 11858 11858 12166 12166 13792 13792 14189 14189 29559 29559 4323 4323 7264 23756 28872 28872 31656 31656 30918 30918 28504 28504 23756 7821 7821 10550 10550 14561 14561 15913 ...
output:
43656653
result:
ok 1 number(s): "43656653"
Test #30:
score: 15
Accepted
time: 532ms
memory: 17332kb
input:
2 199535 116407 31243 37 18798 22113 22113 18798 37 5174 19335 28778 28778 20844 20844 19335 5174 5511 5511 3022 14132 14132 6436 6436 3022 3531 4883 4883 5347 30026 30026 19094 19094 7086 7086 7300 15455 18190 18190 15455 7300 8333 14085 14085 8333 5347 5295 5295 15994 15994 27205 27205 3531 24459 ...
output:
966854518
result:
ok 1 number(s): "966854518"
Subtask #6:
score: 20
Accepted
Dependency #1:
100%
Accepted
Dependency #2:
100%
Accepted
Dependency #3:
100%
Accepted
Dependency #4:
100%
Accepted
Dependency #5:
100%
Accepted
Test #31:
score: 20
Accepted
time: 478ms
memory: 16236kb
input:
993 199975 99931 71 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...
output:
17826237
result:
ok 1 number(s): "17826237"
Test #32:
score: 20
Accepted
time: 960ms
memory: 26512kb
input:
969 199391 177963 160 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 ...
output:
656751841
result:
ok 1 number(s): "656751841"
Test #33:
score: 20
Accepted
time: 523ms
memory: 17528kb
input:
767 194286 115653 202 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 87 87 87 87 87 87 87 87 87 87 87 87 87 87 ...
output:
187115913
result:
ok 1 number(s): "187115913"
Test #34:
score: 20
Accepted
time: 900ms
memory: 24372kb
input:
723 193315 138688 213 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85...
output:
31782139
result:
ok 1 number(s): "31782139"
Test #35:
score: 20
Accepted
time: 902ms
memory: 24712kb
input:
837 196018 143992 172 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 169 ...
output:
569012099
result:
ok 1 number(s): "569012099"
Test #36:
score: 20
Accepted
time: 489ms
memory: 17788kb
input:
178130 199933 99974 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...
output:
642702129
result:
ok 1 number(s): "642702129"
Test #37:
score: 20
Accepted
time: 1018ms
memory: 28436kb
input:
143520 198539 188843 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1...
output:
149968506
result:
ok 1 number(s): "149968506"
Test #38:
score: 20
Accepted
time: 1007ms
memory: 28048kb
input:
46851 198835 187507 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...
output:
207220377
result:
ok 1 number(s): "207220377"
Test #39:
score: 20
Accepted
time: 485ms
memory: 17336kb
input:
126810 195651 102917 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1...
output:
393257556
result:
ok 1 number(s): "393257556"
Test #40:
score: 20
Accepted
time: 435ms
memory: 16292kb
input:
49867 197702 85289 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1...
output:
659224389
result:
ok 1 number(s): "659224389"
Extra Test:
score: 0
Extra Test Passed