QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#658903 | #9488. Do Not Turn Back | ucup-team4435# | AC ✓ | 1659ms | 5304kb | C++20 | 49.5kb | 2024-10-19 17:53:31 | 2024-10-19 17:53:31 |
Judging History
answer
#include <iostream>
#include <type_traits>
template <unsigned Mod>
class ModInt {
static_assert((Mod >> 31) == 0, "`Mod` must less than 2^(31)");
template <typename Int>
static std::enable_if_t<std::is_integral_v<Int>, unsigned> safe_mod(Int v) {
using D = std::common_type_t<Int, unsigned>;
return (v %= (int)Mod) < 0 ? (D)(v + (int)Mod) : (D)v;
}
struct PrivateConstructor {};
static inline PrivateConstructor private_constructor{};
ModInt(PrivateConstructor, unsigned v) : v_(v) {}
unsigned v_;
public:
static unsigned mod() { return Mod; }
static ModInt from_raw(unsigned v) { return ModInt(private_constructor, v); }
ModInt() : v_() {}
template <typename Int, typename std::enable_if_t<std::is_signed_v<Int>, int> = 0>
ModInt(Int v) : v_(safe_mod(v)) {}
template <typename Int, typename std::enable_if_t<std::is_unsigned_v<Int>, int> = 0>
ModInt(Int v) : v_(v % Mod) {}
unsigned val() const { return v_; }
ModInt operator-() const { return from_raw(v_ == 0 ? v_ : Mod - v_); }
ModInt pow(long long e) const {
if (e < 0) return inv().pow(-e);
for (ModInt x(*this), res(from_raw(1));; x *= x) {
if (e & 1) res *= x;
if ((e >>= 1) == 0) return res;
}
}
ModInt inv() const {
int x1 = 1, x3 = 0, a = val(), b = Mod;
while (b) {
int q = a / b, x1_old = x1, a_old = a;
x1 = x3, x3 = x1_old - x3 * q, a = b, b = a_old - b * q;
}
return from_raw(x1 < 0 ? x1 + (int)Mod : x1);
}
template <bool Odd = (Mod & 1)>
std::enable_if_t<Odd, ModInt> div_by_2() const {
if (v_ & 1) return from_raw((v_ + Mod) >> 1);
return from_raw(v_ >> 1);
}
ModInt &operator+=(const ModInt &a) {
if ((v_ += a.v_) >= Mod) v_ -= Mod;
return *this;
}
ModInt &operator-=(const ModInt &a) {
if ((v_ += Mod - a.v_) >= Mod) v_ -= Mod;
return *this;
}
ModInt &operator*=(const ModInt &a) {
v_ = (unsigned long long)v_ * a.v_ % Mod;
return *this;
}
ModInt &operator/=(const ModInt &a) { return *this *= a.inv(); }
friend ModInt operator+(const ModInt &a, const ModInt &b) { return ModInt(a) += b; }
friend ModInt operator-(const ModInt &a, const ModInt &b) { return ModInt(a) -= b; }
friend ModInt operator*(const ModInt &a, const ModInt &b) { return ModInt(a) *= b; }
friend ModInt operator/(const ModInt &a, const ModInt &b) { return ModInt(a) /= b; }
friend bool operator==(const ModInt &a, const ModInt &b) { return a.v_ == b.v_; }
friend bool operator!=(const ModInt &a, const ModInt &b) { return a.v_ != b.v_; }
friend std::istream &operator>>(std::istream &a, ModInt &b) {
int v;
a >> v;
b.v_ = safe_mod(v);
return a;
}
friend std::ostream &operator<<(std::ostream &a, const ModInt &b) { return a << b.val(); }
};
#line 2 "poly.hpp"
#line 2 "poly_basic.hpp"
#line 2 "binomial.hpp"
#include <algorithm>
#include <vector>
template <typename Tp>
class Binomial {
std::vector<Tp> factorial_, invfactorial_;
Binomial() : factorial_{Tp(1)}, invfactorial_{Tp(1)} {}
void preprocess(int n) {
if (const int nn = factorial_.size(); nn < n) {
int k = nn;
while (k < n) k *= 2;
k = std::min<long long>(k, Tp::mod());
factorial_.resize(k);
invfactorial_.resize(k);
for (int i = nn; i < k; ++i) factorial_[i] = factorial_[i - 1] * i;
invfactorial_.back() = factorial_.back().inv();
for (int i = k - 2; i >= nn; --i) invfactorial_[i] = invfactorial_[i + 1] * (i + 1);
}
}
public:
static const Binomial &get(int n) {
static Binomial bin;
bin.preprocess(n);
return bin;
}
Tp binom(int n, int m) const {
return n < m ? Tp() : factorial_[n] * invfactorial_[m] * invfactorial_[n - m];
}
Tp inv(int n) const { return factorial_[n - 1] * invfactorial_[n]; }
Tp factorial(int n) const { return factorial_[n]; }
Tp inv_factorial(int n) const { return invfactorial_[n]; }
};
#line 2 "fft.hpp"
#line 4 "fft.hpp"
#include <cassert>
#include <iterator>
#include <memory>
#line 8 "fft.hpp"
template <typename Tp>
class FftInfo {
static Tp least_quadratic_nonresidue() {
for (int i = 2;; ++i)
if (Tp(i).pow((Tp::mod() - 1) / 2) == -1) return Tp(i);
}
const int ordlog2_;
const Tp zeta_;
const Tp invzeta_;
const Tp imag_;
const Tp invimag_;
mutable std::vector<Tp> root_;
mutable std::vector<Tp> invroot_;
FftInfo()
: ordlog2_(__builtin_ctzll(Tp::mod() - 1)),
zeta_(least_quadratic_nonresidue().pow((Tp::mod() - 1) >> ordlog2_)),
invzeta_(zeta_.inv()), imag_(zeta_.pow(1LL << (ordlog2_ - 2))), invimag_(-imag_),
root_{Tp(1), imag_}, invroot_{Tp(1), invimag_} {}
public:
static const FftInfo &get() {
static FftInfo info;
return info;
}
Tp imag() const { return imag_; }
Tp inv_imag() const { return invimag_; }
Tp zeta() const { return zeta_; }
Tp inv_zeta() const { return invzeta_; }
const std::vector<Tp> &root(int n) const {
// [0, n)
assert((n & (n - 1)) == 0);
if (const int s = root_.size(); s < n) {
root_.resize(n);
for (int i = __builtin_ctz(s); (1 << i) < n; ++i) {
const int j = 1 << i;
root_[j] = zeta_.pow(1LL << (ordlog2_ - i - 2));
for (int k = j + 1; k < j * 2; ++k) root_[k] = root_[k - j] * root_[j];
}
}
return root_;
}
const std::vector<Tp> &inv_root(int n) const {
// [0, n)
assert((n & (n - 1)) == 0);
if (const int s = invroot_.size(); s < n) {
invroot_.resize(n);
for (int i = __builtin_ctz(s); (1 << i) < n; ++i) {
const int j = 1 << i;
invroot_[j] = invzeta_.pow(1LL << (ordlog2_ - i - 2));
for (int k = j + 1; k < j * 2; ++k) invroot_[k] = invroot_[k - j] * invroot_[j];
}
}
return invroot_;
}
};
inline int fft_len(int n) {
--n;
n |= n >> 1, n |= n >> 2, n |= n >> 4, n |= n >> 8;
return (n | n >> 16) + 1;
}
template <typename Iterator>
inline void fft_n(Iterator a, int n) {
using Tp = typename std::iterator_traits<Iterator>::value_type;
assert((n & (n - 1)) == 0);
for (int j = 0; j < n / 2; ++j) {
auto u = a[j], v = a[j + n / 2];
a[j] = u + v, a[j + n / 2] = u - v;
}
auto &&root = FftInfo<Tp>::get().root(n / 2);
for (int i = n / 2; i >= 2; i /= 2) {
for (int j = 0; j < i / 2; ++j) {
auto u = a[j], v = a[j + i / 2];
a[j] = u + v, a[j + i / 2] = u - v;
}
for (int j = i, m = 1; j < n; j += i, ++m)
for (int k = j; k < j + i / 2; ++k) {
auto u = a[k], v = a[k + i / 2] * root[m];
a[k] = u + v, a[k + i / 2] = u - v;
}
}
}
template <typename Tp>
inline void fft(std::vector<Tp> &a) {
fft_n(a.begin(), a.size());
}
template <typename Iterator>
inline void inv_fft_n(Iterator a, int n) {
using Tp = typename std::iterator_traits<Iterator>::value_type;
assert((n & (n - 1)) == 0);
auto &&root = FftInfo<Tp>::get().inv_root(n / 2);
for (int i = 2; i < n; i *= 2) {
for (int j = 0; j < i / 2; ++j) {
auto u = a[j], v = a[j + i / 2];
a[j] = u + v, a[j + i / 2] = u - v;
}
for (int j = i, m = 1; j < n; j += i, ++m)
for (int k = j; k < j + i / 2; ++k) {
auto u = a[k], v = a[k + i / 2];
a[k] = u + v, a[k + i / 2] = (u - v) * root[m];
}
}
const Tp iv = Tp::mod() - Tp::mod() / n;
for (int j = 0; j < n / 2; ++j) {
auto u = a[j] * iv, v = a[j + n / 2] * iv;
a[j] = u + v, a[j + n / 2] = u - v;
}
}
template <typename Tp>
inline void inv_fft(std::vector<Tp> &a) {
inv_fft_n(a.begin(), a.size());
}
template <typename Tp>
inline std::vector<Tp> convolution_fft(std::vector<Tp> a, std::vector<Tp> b) {
if (a.empty() || b.empty()) return {};
const int n = a.size();
const int m = b.size();
const int len = fft_len(n + m - 1);
a.resize(len);
b.resize(len);
fft(a);
fft(b);
for (int i = 0; i < len; ++i) a[i] *= b[i];
inv_fft(a);
a.resize(n + m - 1);
return a;
}
template <typename Tp>
inline std::vector<Tp> square_fft(std::vector<Tp> a) {
if (a.empty()) return {};
const int n = a.size();
const int len = fft_len(n * 2 - 1);
a.resize(len);
fft(a);
for (int i = 0; i < len; ++i) a[i] *= a[i];
inv_fft(a);
a.resize(n * 2 - 1);
return a;
}
template <typename Tp>
inline std::vector<Tp> convolution_naive(const std::vector<Tp> &a, const std::vector<Tp> &b) {
if (a.empty() || b.empty()) return {};
const int n = a.size();
const int m = b.size();
std::vector<Tp> res(n + m - 1);
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j) res[i + j] += a[i] * b[j];
return res;
}
template <typename Tp>
inline std::vector<Tp> convolution(const std::vector<Tp> &a, const std::vector<Tp> &b) {
if (std::min(a.size(), b.size()) < 60) return convolution_naive(a, b);
if (std::addressof(a) == std::addressof(b)) return square_fft(a);
return convolution_fft(a, b);
}
#line 2 "fps_basic.hpp"
#line 2 "semi_relaxed_conv.hpp"
#line 6 "semi_relaxed_conv.hpp"
#include <utility>
#line 8 "semi_relaxed_conv.hpp"
// returns coefficients generated by closure
// closure: gen(index, current_product)
template <typename Tp, typename Closure>
inline std::enable_if_t<std::is_invocable_r_v<Tp, Closure, int, const std::vector<Tp> &>,
std::vector<Tp>>
semi_relaxed_convolution(const std::vector<Tp> &A, Closure gen, int n) {
enum { BaseCaseSize = 32 };
static_assert((BaseCaseSize & (BaseCaseSize - 1)) == 0);
static const int Block[] = {16, 16, 16, 16, 16};
static const int BlockSize[] = {
BaseCaseSize,
BaseCaseSize * Block[0],
BaseCaseSize * Block[0] * Block[1],
BaseCaseSize * Block[0] * Block[1] * Block[2],
BaseCaseSize * Block[0] * Block[1] * Block[2] * Block[3],
BaseCaseSize * Block[0] * Block[1] * Block[2] * Block[3] * Block[4],
};
// returns (which_block, level)
auto blockinfo = [](int ind) {
int i = ind / BaseCaseSize, lv = 0;
while ((i & (Block[lv] - 1)) == 0) i /= Block[lv++];
return std::make_pair(i & (Block[lv] - 1), lv);
};
std::vector<Tp> B(n), AB(n);
std::vector<std::vector<std::vector<Tp>>> dftA, dftB;
for (int i = 0; i < n; ++i) {
const int s = i & (BaseCaseSize - 1);
// blocked contribution
if (i >= BaseCaseSize && s == 0) {
const auto [j, lv] = blockinfo(i);
const int blocksize = BlockSize[lv];
if (blocksize * j == i) {
if ((int)dftA.size() == lv) {
dftA.emplace_back();
dftB.emplace_back(Block[lv] - 1);
}
if ((j - 1) * blocksize < (int)A.size()) {
dftA[lv]
.emplace_back(A.begin() + (j - 1) * blocksize,
A.begin() + std::min((j + 1) * blocksize, (int)A.size()))
.resize(blocksize * 2);
fft(dftA[lv][j - 1]);
} else {
dftA[lv].emplace_back(blocksize * 2);
}
}
dftB[lv][j - 1].resize(blocksize * 2);
std::copy_n(B.begin() + (i - blocksize), blocksize, dftB[lv][j - 1].begin());
std::fill_n(dftB[lv][j - 1].begin() + blocksize, blocksize, 0);
fft(dftB[lv][j - 1]);
// middle product
std::vector<Tp> mp(blocksize * 2);
for (int k = 0; k < j; ++k)
for (int l = 0; l < blocksize * 2; ++l)
mp[l] += dftA[lv][j - 1 - k][l] * dftB[lv][k][l];
inv_fft(mp);
for (int k = 0; k < blocksize && i + k < n; ++k) AB[i + k] += mp[k + blocksize];
}
// basecase contribution
for (int j = std::max(i - s, i - (int)A.size() + 1); j < i; ++j) AB[i] += A[i - j] * B[j];
B[i] = gen(i, AB);
if (!A.empty()) AB[i] += A[0] * B[i];
}
return B;
}
#line 7 "fps_basic.hpp"
template <typename Tp>
inline int order(const std::vector<Tp> &a) {
for (int i = 0; i < (int)a.size(); ++i)
if (a[i] != 0) return i;
return -1;
}
template <typename Tp>
inline std::vector<Tp> inv(const std::vector<Tp> &a, int n) {
assert(!a.empty());
if (n <= 0) return {};
return semi_relaxed_convolution(
a, [v = a[0].inv()](int n, auto &&c) { return n == 0 ? v : -c[n] * v; }, n);
}
template <typename Tp>
inline std::vector<Tp> div(const std::vector<Tp> &a, const std::vector<Tp> &b, int n) {
assert(!b.empty());
if (n <= 0) return {};
return semi_relaxed_convolution(
b,
[&, v = b[0].inv()](int n, auto &&c) {
if (n < (int)a.size()) return (a[n] - c[n]) * v;
return -c[n] * v;
},
n);
}
template <typename Tp>
inline std::vector<Tp> deriv(const std::vector<Tp> &a) {
const int n = (int)a.size() - 1;
if (n <= 0) return {};
std::vector<Tp> res(n);
for (int i = 1; i <= n; ++i) res[i - 1] = a[i] * i;
return res;
}
template <typename Tp>
inline std::vector<Tp> integr(const std::vector<Tp> &a, Tp c = {}) {
const int n = a.size() + 1;
auto &&bin = Binomial<Tp>::get(n);
std::vector<Tp> res(n);
res[0] = c;
for (int i = 1; i < n; ++i) res[i] = a[i - 1] * bin.inv(i);
return res;
}
template <typename Tp>
inline std::vector<Tp> log(const std::vector<Tp> &a, int n) {
return integr(div(deriv(a), a, n - 1));
}
template <typename Tp>
inline std::vector<Tp> exp(const std::vector<Tp> &a, int n) {
if (n <= 0) return {};
assert(!a.empty() && a[0] == 0);
return semi_relaxed_convolution(
deriv(a),
[bin = Binomial<Tp>::get(n)](int n, auto &&c) {
return n == 0 ? Tp(1) : c[n - 1] * bin.inv(n);
},
n);
}
template <typename Tp>
inline std::vector<Tp> pow(std::vector<Tp> a, long long e, int n) {
if (n <= 0) return {};
if (e == 0) {
std::vector<Tp> res(n);
res[0] = 1;
return res;
}
const int o = order(a);
if (o < 0 || o > n / e || (o == n / e && n % e == 0)) return std::vector<Tp>(n);
if (o != 0) a.erase(a.begin(), a.begin() + o);
const Tp ia0 = a[0].inv();
const Tp a0e = a[0].pow(e);
const Tp me = e;
for (int i = 0; i < (int)a.size(); ++i) a[i] *= ia0;
a = log(a, n - o * e);
for (int i = 0; i < (int)a.size(); ++i) a[i] *= me;
a = exp(a, n - o * e);
for (int i = 0; i < (int)a.size(); ++i) a[i] *= a0e;
a.insert(a.begin(), o * e, 0);
return a;
}
#line 10 "poly_basic.hpp"
template <typename Tp>
inline int degree(const std::vector<Tp> &a) {
int n = (int)a.size() - 1;
while (n >= 0 && a[n] == 0) --n;
return n;
}
template <typename Tp>
inline void shrink(std::vector<Tp> &a) {
a.resize(degree(a) + 1);
}
template <typename Tp>
inline std::vector<Tp> taylor_shift(std::vector<Tp> a, Tp c) {
const int n = a.size();
auto &&bin = Binomial<Tp>::get(n);
for (int i = 0; i < n; ++i) a[i] *= bin.factorial(i);
Tp cc = 1;
std::vector<Tp> b(n);
for (int i = 0; i < n; ++i) {
b[i] = cc * bin.inv_factorial(i);
cc *= c;
}
std::reverse(a.begin(), a.end());
auto ab = convolution(a, b);
ab.resize(n);
std::reverse(ab.begin(), ab.end());
for (int i = 0; i < n; ++i) ab[i] *= bin.inv_factorial(i);
return ab;
}
// returns (quotient, remainder)
// O(deg(Q)deg(B))
template <typename Tp>
inline std::pair<std::vector<Tp>, std::vector<Tp>> euclidean_div_naive(const std::vector<Tp> &A,
const std::vector<Tp> &B) {
const int degA = degree(A);
const int degB = degree(B);
assert(degB >= 0);
const int degQ = degA - degB;
if (degQ < 0) return {std::vector<Tp>{Tp(0)}, A};
std::vector<Tp> Q(degQ + 1), R = A;
const auto inv = B[degB].inv();
for (int i = degQ, n = degA; i >= 0; --i)
if ((Q[i] = R[n--] * inv) != 0)
for (int j = 0; j <= degB; ++j) R[i + j] -= Q[i] * B[j];
R.resize(degB);
return {Q, R};
}
// O(min(deg(Q)^2,deg(Q)deg(B)))
template <typename Tp>
inline std::vector<Tp> euclidean_div_quotient_naive(const std::vector<Tp> &A,
const std::vector<Tp> &B) {
const int degA = degree(A);
const int degB = degree(B);
assert(degB >= 0);
const int degQ = degA - degB;
if (degQ < 0) return {Tp(0)};
const auto inv = B[degB].inv();
std::vector<Tp> Q(degQ + 1);
for (int i = 0; i <= degQ; ++i) {
for (int j = 1; j <= std::min(i, degB); ++j) Q[degQ - i] += B[degB - j] * Q[degQ - i + j];
Q[degQ - i] = (A[degA - i] - Q[degQ - i]) * inv;
}
return Q;
}
// returns (quotient, remainder)
template <typename Tp>
inline std::pair<std::vector<Tp>, std::vector<Tp>> euclidean_div(const std::vector<Tp> &A,
const std::vector<Tp> &B) {
const int degA = degree(A);
const int degB = degree(B);
assert(degB >= 0);
// A = Q*B + R => A/B = Q + R/B in R((x^(-1)))
const int degQ = degA - degB;
if (degQ < 0) return {std::vector<Tp>{Tp(0)}, A};
if (degQ < 60 || degB < 60) return euclidean_div_naive(A, B);
auto Q = div(std::vector(A.rend() - (degA + 1), A.rend()),
std::vector(B.rend() - (degB + 1), B.rend()), degQ + 1);
std::reverse(Q.begin(), Q.end());
// returns a mod (x^n-1)
auto make_cyclic = [](const std::vector<Tp> &a, int n) {
assert((n & (n - 1)) == 0);
std::vector<Tp> b(n);
for (int i = 0; i < (int)a.size(); ++i) b[i & (n - 1)] += a[i];
return b;
};
const int len = fft_len(std::max(degB, 1));
const auto cyclicA = make_cyclic(A, len);
auto cyclicB = make_cyclic(B, len);
auto cyclicQ = make_cyclic(Q, len);
fft(cyclicQ);
fft(cyclicB);
for (int i = 0; i < len; ++i) cyclicQ[i] *= cyclicB[i];
inv_fft(cyclicQ);
// R = A - QB mod (x^n-1) (n >= degB)
std::vector<Tp> R(degB);
for (int i = 0; i < degB; ++i) R[i] = cyclicA[i] - cyclicQ[i];
return {Q, R};
}
template <typename Tp>
inline std::vector<Tp> euclidean_div_quotient(const std::vector<Tp> &A, const std::vector<Tp> &B) {
const int degA = degree(A);
const int degB = degree(B);
assert(degB >= 0);
// A = Q*B + R => A/B = Q + R/B in R((x^(-1)))
const int degQ = degA - degB;
if (degQ < 0) return {Tp(0)};
if (std::min(degQ, degB) < 60) return euclidean_div_quotient_naive(A, B);
auto Q = div(std::vector(A.rend() - (degA + 1), A.rend()),
std::vector(B.rend() - (degB + 1), B.rend()), degQ + 1);
std::reverse(Q.begin(), Q.end());
return Q;
}
#line 5 "poly.hpp"
#include <array>
#line 8 "poly.hpp"
#include <tuple>
#line 11 "poly.hpp"
template <typename Tp>
class Poly : public std::vector<Tp> {
using Base = std::vector<Tp>;
public:
using Base::Base;
static Poly from_vector(const std::vector<Tp> &V) { return Poly(V.begin(), V.end()); }
int deg() const { return degree(*this); }
int ord() const { return order(*this); }
Poly rev() const {
const int d = deg();
Poly res(d + 1);
for (int i = d; i >= 0; --i) res[i] = Base::operator[](d - i);
return res;
}
Poly slice(int L, int R) const {
Poly res(R - L);
for (int i = L; i < std::min(R, (int)Base::size()); ++i) res[i - L] = Base::operator[](i);
return res;
}
Poly trunc(int D) const {
Poly res(D);
for (int i = 0; i < std::min(D, (int)Base::size()); ++i) res[i] = Base::operator[](i);
return res;
}
Poly &shrink() {
Base::resize(deg() + 1);
return *this;
}
Tp lc() const {
const int d = deg();
return d == -1 ? Tp() : Base::operator[](d);
}
Poly operator-() const {
const int d = deg();
Poly res(d + 1);
for (int i = 0; i <= d; ++i) res[i] = -Base::operator[](i);
res.shrink();
return res;
}
std::pair<Poly, Poly> divmod(const Poly &R) const {
const auto [q, r] = euclidean_div(*this, R);
return std::make_pair(from_vector(q), from_vector(r));
}
Poly &operator+=(const Poly &R) {
if (Base::size() < R.size()) Base::resize(R.size());
for (int i = 0; i < (int)R.size(); ++i) Base::operator[](i) += R[i];
return shrink();
}
Poly &operator-=(const Poly &R) {
if (Base::size() < R.size()) Base::resize(R.size());
for (int i = 0; i < (int)R.size(); ++i) Base::operator[](i) -= R[i];
return shrink();
}
Poly &operator*=(const Poly &R) {
Base::operator=(convolution(*this, R));
return shrink();
}
Poly &operator/=(const Poly &R) {
Base::operator=(euclidean_div_quotient(*this, R));
return shrink();
}
Poly &operator%=(const Poly &R) {
Base::operator=(divmod(R).second);
return shrink();
}
Poly &operator<<=(int D) {
if (D > 0) {
Base::insert(Base::begin(), D, Tp());
} else if (D < 0) {
if (-D < (int)Base::size()) {
Base::erase(Base::begin(), Base::begin() + (-D));
} else {
Base::clear();
}
}
return shrink();
}
Poly &operator>>=(int D) { return operator<<=(-D); }
friend Poly operator+(const Poly &L, const Poly &R) { return Poly(L) += R; }
friend Poly operator-(const Poly &L, const Poly &R) { return Poly(L) -= R; }
friend Poly operator*(const Poly &L, const Poly &R) { return Poly(L) *= R; }
friend Poly operator/(const Poly &L, const Poly &R) { return Poly(L) /= R; }
friend Poly operator%(const Poly &L, const Poly &R) { return Poly(L) %= R; }
friend Poly operator<<(const Poly &L, int D) { return Poly(L) <<= D; }
friend Poly operator>>(const Poly &L, int D) { return Poly(L) >>= D; }
friend std::ostream &operator<<(std::ostream &L, const Poly &R) {
L << '[';
const int d = R.deg();
if (d < 0) {
L << '0';
} else {
for (int i = 0; i <= d; ++i) {
L << R[i];
if (i == 1) L << "*x";
if (i > 1) L << "*x^" << i;
if (i != d) L << " + ";
}
}
return L << ']';
}
};
// 2x2 matrix for Euclidean algorithm
template <typename Tp>
class GCDMatrix : public std::array<std::array<Tp, 2>, 2> {
public:
GCDMatrix(const Tp &x00, const Tp &x01, const Tp &x10, const Tp &x11)
: std::array<std::array<Tp, 2>, 2>{std::array{x00, x01}, std::array{x10, x11}} {}
GCDMatrix operator*(const GCDMatrix &R) const {
return {(*this)[0][0] * R[0][0] + (*this)[0][1] * R[1][0],
(*this)[0][0] * R[0][1] + (*this)[0][1] * R[1][1],
(*this)[1][0] * R[0][0] + (*this)[1][1] * R[1][0],
(*this)[1][0] * R[0][1] + (*this)[1][1] * R[1][1]};
}
std::array<Tp, 2> operator*(const std::array<Tp, 2> &R) const {
return {(*this)[0][0] * R[0] + (*this)[0][1] * R[1],
(*this)[1][0] * R[0] + (*this)[1][1] * R[1]};
}
Tp det() const { return (*this)[0][0] * (*this)[1][1] - (*this)[0][1] * (*this)[1][0]; }
GCDMatrix adj() const { return {(*this)[1][1], -(*this)[0][1], -(*this)[1][0], (*this)[0][0]}; }
};
// returns M s.t. deg(M) <= d and deg(M21*A+M22*B) < max(deg(A),deg(B))-d
// det(M) in {-1,1}
// see:
// [1]: Daniel J. Bernstein. Fast multiplication and its applications.
template <typename Tp>
inline GCDMatrix<Poly<Tp>> hgcd(const Poly<Tp> &A, const Poly<Tp> &B, int d) {
using Mat = GCDMatrix<Poly<Tp>>;
assert(!(A.deg() < 0 && B.deg() < 0));
if (A.deg() < B.deg()) return hgcd(B, A, d) * Mat({}, {Tp(1)}, {Tp(1)}, {});
if (A.deg() < d) return hgcd(A, B, A.deg());
if (B.deg() < 0 || B.deg() < A.deg() - d) return Mat({Tp(1)}, {}, {}, {Tp(1)});
if (int dd = A.deg() - d * 2; dd > 0) return hgcd(A >> dd, B >> dd, d);
if (d == 0) return Mat({}, {Tp(1)}, {Tp(1)}, -(A / B));
const auto M = hgcd(A, B, d / 2);
const auto D = M[1][0] * A + M[1][1] * B;
if (D.deg() < A.deg() - d) return M;
const auto C = M[0][0] * A + M[0][1] * B;
const auto [Q, R] = C.divmod(D);
return hgcd(D, R, D.deg() - (A.deg() - d)) * Mat({}, {Tp(1)}, {Tp(1)}, -Q) * M;
}
template <typename Tp>
inline std::tuple<Poly<Tp>, Poly<Tp>, Poly<Tp>> xgcd(const Poly<Tp> &A, const Poly<Tp> &B) {
const auto M = hgcd(A, B, std::max(A.deg(), B.deg()));
return std::make_tuple(M[0][0], M[0][1], M[0][0] * A + M[0][1] * B);
}
template <typename Tp>
inline std::pair<Poly<Tp>, Poly<Tp>> inv_gcd(const Poly<Tp> &A, const Poly<Tp> &B) {
const auto M = hgcd(A, B, std::max(A.deg(), B.deg()));
return std::make_pair(M[0][0], M[0][0] * A + M[0][1] * B);
}
// returns P,Q s.t. [x^([-k,-1])]P/Q=[x^([-k,-1])]A/B
// where P,Q in F[x], deg(Q) is minimized
// requires deg(A)<deg(B)
template <typename Tp>
inline std::pair<Poly<Tp>, Poly<Tp>> rational_function_approximation(const Poly<Tp> &A,
const Poly<Tp> &B, int k) {
auto M = hgcd(B, A, k / 2);
const auto [C, D] = M * std::array{B, A};
if (D.deg() >= 0 && D.deg() - C.deg() >= -(k - (B.deg() - C.deg()) * 2))
M = GCDMatrix<Poly<Tp>>({}, {Tp(1)}, {Tp(1)}, -(C / D)) * M;
return std::make_pair(M.adj()[1][0], M.adj()[0][0]);
}
// returns [x^([-k,-1])]A/B
// requires deg(A)<deg(B)
template <typename Tp>
inline std::vector<Tp> rational_function_to_series(const Poly<Tp> &A, const Poly<Tp> &B, int k) {
return (((A << k) / B).rev() << (B.deg() - A.deg() - 1)).slice(0, k);
}
using mint = ModInt<998244353>;
using namespace std;
#define len(a) int(a.size())
#define all(a) begin(a), end(a)
namespace lol {
#include <algorithm>
#include <bit>
// ============
#include <algorithm>
// ============
#include <array>
#include <vector>
// ============
#include <cassert>
#include <iostream>
#include <type_traits>
// ============
#include <utility>
constexpr bool is_prime(unsigned n) {
if (n == 0 || n == 1) {
return false;
}
for (unsigned i = 2; i * i <= n; ++i) {
if (n % i == 0) {
return false;
}
}
return true;
}
constexpr unsigned mod_pow(unsigned x, unsigned y, unsigned mod) {
unsigned ret = 1, self = x;
while (y != 0) {
if (y & 1) {
ret = (unsigned)((unsigned long long)ret * self % mod);
}
self = (unsigned)((unsigned long long)self * self % mod);
y /= 2;
}
return ret;
}
template <unsigned mod>
constexpr unsigned primitive_root() {
static_assert(is_prime(mod), "`mod` must be a prime number.");
if (mod == 2) {
return 1;
}
unsigned primes[32] = {};
int it = 0;
{
unsigned m = mod - 1;
for (unsigned i = 2; i * i <= m; ++i) {
if (m % i == 0) {
primes[it++] = i;
while (m % i == 0) {
m /= i;
}
}
}
if (m != 1) {
primes[it++] = m;
}
}
for (unsigned i = 2; i < mod; ++i) {
bool ok = true;
for (int j = 0; j < it; ++j) {
if (mod_pow(i, (mod - 1) / primes[j], mod) == 1) {
ok = false;
break;
}
}
if (ok) return i;
}
return 0;
}
// y >= 1
template <typename T>
constexpr T safe_mod(T x, T y) {
x %= y;
if (x < 0) {
x += y;
}
return x;
}
// y != 0
template <typename T>
constexpr T floor_div(T x, T y) {
if (y < 0) {
x *= -1;
y *= -1;
}
if (x >= 0) {
return x / y;
} else {
return -((-x + y - 1) / y);
}
}
// y != 0
template <typename T>
constexpr T ceil_div(T x, T y) {
if (y < 0) {
x *= -1;
y *= -1;
}
if (x >= 0) {
return (x + y - 1) / y;
} else {
return -(-x / y);
}
}
// b >= 1
// returns (g, x) s.t. g = gcd(a, b), a * x = g (mod b), 0 <= x < b / g
// from ACL
template <typename T>
std::pair<T, T> extgcd(T a, T b) {
a = safe_mod(a, b);
T s = b, t = a, m0 = 0, m1 = 1;
while (t) {
T u = s / t;
s -= t * u;
m0 -= m1 * u;
std::swap(s, t);
std::swap(m0, m1);
}
if (m0 < 0) {
m0 += b / s;
}
return std::pair<T, T>(s, m0);
}
// b >= 1
// returns (g, x, y) s.t. g = gcd(a, b), a * x + b * y = g, 0 <= x < b / g, |y| < max(2, |a| / g)
template <typename T>
std::tuple<T, T, T> extgcd2(T a, T b) {
T _a = safe_mod(a, b);
T quot = (a - _a) / b;
T x00 = 0, x01 = 1, y0 = b;
T x10 = 1, x11 = -quot, y1 = _a;
while (y1) {
T u = y0 / y1;
x00 -= u * x10;
x01 -= u * x11;
y0 -= u * y1;
std::swap(x00, x10);
std::swap(x01, x11);
std::swap(y0, y1);
}
if (x00 < 0) {
x00 += b / y0;
x01 -= a / y0;
}
return std::tuple<T, T, T>(y0, x00, x01);
}
// gcd(x, m) == 1
template <typename T>
T inv_mod(T x, T m) {
return extgcd(x, m).second;
}
// ============
template <unsigned mod>
struct ModInt {
static_assert(mod != 0, "`mod` must not be equal to 0.");
static_assert(mod < (1u << 31),
"`mod` must be less than (1u << 31) = 2147483648.");
unsigned val;
static constexpr unsigned get_mod() { return mod; }
constexpr ModInt() : val(0) {}
template <typename T, std::enable_if_t<std::is_signed_v<T>> * = nullptr>
constexpr ModInt(T x)
: val((unsigned)((long long)x % (long long)mod + (x < 0 ? mod : 0))) {}
template <typename T, std::enable_if_t<std::is_unsigned_v<T>> * = nullptr>
constexpr ModInt(T x) : val((unsigned)(x % mod)) {}
static constexpr ModInt raw(unsigned x) {
ModInt<mod> ret;
ret.val = x;
return ret;
}
constexpr unsigned get_val() const { return val; }
constexpr ModInt operator+() const { return *this; }
constexpr ModInt operator-() const { return ModInt<mod>(0u) - *this; }
constexpr ModInt &operator+=(const ModInt &rhs) {
val += rhs.val;
if (val >= mod) val -= mod;
return *this;
}
constexpr ModInt &operator-=(const ModInt &rhs) {
val -= rhs.val;
if (val >= mod) val += mod;
return *this;
}
constexpr ModInt &operator*=(const ModInt &rhs) {
val = (unsigned long long)val * rhs.val % mod;
return *this;
}
constexpr ModInt &operator/=(const ModInt &rhs) {
val = (unsigned long long)val * rhs.inv().val % mod;
return *this;
}
friend constexpr ModInt operator+(const ModInt &lhs, const ModInt &rhs) {
return ModInt<mod>(lhs) += rhs;
}
friend constexpr ModInt operator-(const ModInt &lhs, const ModInt &rhs) {
return ModInt<mod>(lhs) -= rhs;
}
friend constexpr ModInt operator*(const ModInt &lhs, const ModInt &rhs) {
return ModInt<mod>(lhs) *= rhs;
}
friend constexpr ModInt operator/(const ModInt &lhs, const ModInt &rhs) {
return ModInt<mod>(lhs) /= rhs;
}
constexpr ModInt pow(unsigned long long x) const {
ModInt<mod> ret = ModInt<mod>::raw(1);
ModInt<mod> self = *this;
while (x != 0) {
if (x & 1) ret *= self;
self *= self;
x >>= 1;
}
return ret;
}
constexpr ModInt inv() const {
static_assert(is_prime(mod), "`mod` must be a prime number.");
assert(val != 0);
return this->pow(mod - 2);
}
friend std::istream &operator>>(std::istream &is, ModInt<mod> &x) {
long long val;
is >> val;
x.val = val % mod + (val < 0 ? mod : 0);
return is;
}
friend std::ostream &operator<<(std::ostream &os, const ModInt<mod> &x) {
os << x.val;
return os;
}
friend bool operator==(const ModInt &lhs, const ModInt &rhs) {
return lhs.val == rhs.val;
}
friend bool operator!=(const ModInt &lhs, const ModInt &rhs) {
return lhs.val != rhs.val;
}
};
template <unsigned mod>
void debug(ModInt<mod> x) {
std::cerr << x.val;
}
// ============
constexpr int ctz_constexpr(unsigned n) {
int x = 0;
while (!(n & (1u << x))) {
++x;
}
return x;
}
template <unsigned MOD>
struct FFTRoot {
static constexpr unsigned R = ctz_constexpr(MOD - 1);
std::array<ModInt<MOD>, R + 1> root, iroot;
std::array<ModInt<MOD>, R> rate2, irate2;
std::array<ModInt<MOD>, R - 1> rate3, irate3;
std::array<ModInt<MOD>, R + 1> inv2;
constexpr FFTRoot() : root{}, iroot{}, rate2{}, irate2{}, rate3{}, irate3{}, inv2{} {
unsigned pr = primitive_root<MOD>();
root[R] = ModInt<MOD>(pr).pow(MOD >> R);
iroot[R] = root[R].inv();
for (int i = R - 1; i >= 0; --i) {
root[i] = root[i + 1] * root[i + 1];
iroot[i] = iroot[i + 1] * iroot[i + 1];
}
ModInt<MOD> prod(1), iprod(1);
for (int i = 0; i < (int)R - 1; ++i) {
rate2[i] = prod * root[i + 2];
irate2[i] = iprod * iroot[i + 2];
prod *= iroot[i + 2];
iprod *= root[i + 2];
}
prod = ModInt<MOD>(1);
iprod = ModInt<MOD>(1);
for (int i = 0; i < (int)R - 2; ++i) {
rate3[i] = prod * root[i + 3];
irate3[i] = iprod * iroot[i + 3];
prod *= iroot[i + 3];
iprod *= root[i + 3];
}
ModInt<MOD> i2 = ModInt<MOD>(2).inv();
inv2[0] = ModInt<MOD>(1);
for (int i = 0; i < (int)R; ++i) {
inv2[i + 1] = inv2[i] * i2;
}
}
};
template <typename M>
void fft(M *a, int n) {
using ull = unsigned long long;
static_assert(M::get_mod() < (1u << 30));
static constexpr FFTRoot<M::get_mod()> fftroot;
static constexpr ull CEIL = 2ULL * M::get_mod() * M::get_mod();
int l = __builtin_ctz(n);
int ph = 0;
while (ph < l) {
if (ph + 1 == l) {
int b = 1 << ph;
M z = M::raw(1);
for (int i = 0; i < b; ++i) {
int offset = i << 1;
M x = a[offset];
M y = a[offset + 1] * z;
a[offset] = x + y;
a[offset + 1] = x - y;
z *= fftroot.rate2[__builtin_ctz(~i)];
}
++ph;
} else {
int bl = 1 << ph;
int wd = 1 << (l - 2 - ph);
M zeta = M::raw(1);
for (int i = 0; i < bl; ++i) {
int offset = i << (l - ph);
M zeta2 = zeta * zeta;
M zeta3 = zeta2 * zeta;
for (int j = 0; j < wd; ++j) {
ull w = a[offset + j].val;
ull x = (ull)a[offset + j + wd].val * zeta.val;
ull y = (ull)a[offset + j + 2 * wd].val * zeta2.val;
ull z = (ull)a[offset + j + 3 * wd].val * zeta3.val;
ull ix_m_iz = (CEIL + x - z) % M::get_mod() * fftroot.root[2].val;
a[offset + j] = M(w + x + y + z);
a[offset + j + wd] = M(CEIL + w - x + y - z);
a[offset + j + 2 * wd] = M(CEIL + w - y + ix_m_iz);
a[offset + j + 3 * wd] = M(CEIL + w - y - ix_m_iz);
}
zeta *= fftroot.rate3[__builtin_ctz(~i)];
}
ph += 2;
}
}
}
template <typename M>
void ifft(M *a, int n) {
using ull = unsigned long long;
static_assert(M::get_mod() < (1u << 30));
static constexpr FFTRoot<M::get_mod()> fftroot;
int l = __builtin_ctz(n);
int ph = l;
while (ph > 0) {
if (ph == 1) {
--ph;
int wd = 1 << (l - 1);
for (int i = 0; i < wd; ++i) {
M x = a[i];
M y = a[i + wd];
a[i] = x + y;
a[i + wd] = x - y;
}
} else {
ph -= 2;
int bl = 1 << ph;
int wd = 1 << (l - 2 - ph);
M zeta = M::raw(1);
for (int i = 0; i < bl; ++i) {
int offset = i << (l - ph);
M zeta2 = zeta * zeta;
M zeta3 = zeta2 * zeta;
for (int j = 0; j < wd; ++j) {
unsigned w = a[offset + j].val;
unsigned x = a[offset + j + wd].val;
unsigned y = a[offset + j + 2 * wd].val;
unsigned z = a[offset + j + 3 * wd].val;
unsigned iy_m_iz = (ull)(M::get_mod() + y - z) * fftroot.root[2].val % M::get_mod();
a[offset + j] = M(w + x + y + z);
a[offset + j + wd] = M((ull)zeta.val * (2 * M::get_mod() + w - x - iy_m_iz));
a[offset + j + 2 * wd] = M((ull)zeta2.val * (2 * M::get_mod() + w + x - y - z));
a[offset + j + 3 * wd] = M((ull)zeta3.val * (M::get_mod() + w - x + iy_m_iz));
}
zeta *= fftroot.irate3[__builtin_ctz(~i)];
}
}
}
for (int i = 0; i < n; ++i) {
a[i] *= fftroot.inv2[l];
}
}
template <typename M>
void fft(std::vector<M> &a) {
fft(a.data(), (int)a.size());
}
template <typename M>
void ifft(std::vector<M> &a) {
ifft(a.data(), (int)a.size());
}
template <typename M>
std::vector<M> convolve_naive(const std::vector<M> &a,
const std::vector<M> &b) {
int n = (int)a.size();
int m = (int)b.size();
std::vector<M> c(n + m - 1);
if (n < m) {
for (int j = 0; j < m; ++j) {
for (int i = 0; i < n; ++i) {
c[i + j] += a[i] * b[j];
}
}
} else {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
c[i + j] += a[i] * b[j];
}
}
}
return c;
}
template <typename M>
std::vector<M> convolve_fft(std::vector<M> a, std::vector<M> b) {
int n = (int)a.size() + (int)b.size() - 1;
int m = 1;
while (m < n) {
m <<= 1;
}
bool shr = false;
M last;
if (n >= 3 && n == m / 2 + 1) {
shr = true;
last = a.back() * b.back();
m /= 2;
while ((int)a.size() > m) {
a[(int)a.size() - 1 - m] += a.back();
a.pop_back();
}
while ((int)b.size() > m) {
b[(int)b.size() - 1 - m] += b.back();
b.pop_back();
}
}
a.resize(m);
b.resize(m);
fft(a);
fft(b);
for (int i = 0; i < m; ++i) {
a[i] *= b[i];
}
ifft(a);
a.resize(n);
if (shr) {
a[0] -= last;
a[n - 1] = last;
}
return a;
}
template <typename M>
std::vector<M> convolve(const std::vector<M> &a, const std::vector<M> &b) {
if (a.empty() || b.empty()) {
return std::vector<M>(0);
}
if (std::min(a.size(), b.size()) <= 60) {
return convolve_naive(a, b);
} else {
return convolve_fft(a, b);
}
}
// ============
// 10 FFT(n)
template <typename T>
std::vector<T> fps_inv(std::vector<T> f) {
assert(!f.empty() && f[0] != T(0));
std::vector<T> g(1, T(1) / f[0]);
while (g.size() < f.size()) {
int n = (int)g.size();
std::vector<T> fft_f(2 * n), fft_g(2 * n);
std::copy(f.begin(), f.begin() + std::min(2 * n, (int)f.size()),
fft_f.begin());
std::copy(g.begin(), g.end(), fft_g.begin());
fft(fft_f);
fft(fft_g);
for (int i = 0; i < 2 * n; ++i) {
fft_f[i] *= fft_g[i];
}
ifft(fft_f);
std::fill(fft_f.begin(), fft_f.begin() + n, T(0));
fft(fft_f);
for (int i = 0; i < 2 * n; ++i) {
fft_f[i] *= fft_g[i];
}
ifft(fft_f);
g.resize(2 * n);
for (int i = n; i < 2 * n; ++i) {
g[i] = -fft_f[i];
}
}
g.resize(f.size());
return g;
}
// ============
template <typename M>
void extend_fft(std::vector<M> &a) {
static constexpr FFTRoot<M::get_mod()> fft_root;
int n = (int)a.size();
std::copy(a.begin(), a.begin() + n / 2, a.begin() + n / 2);
ifft(a.data() + n / 2, n / 2);
M pw(1);
M r = fft_root.root[std::bit_width((unsigned)n) - 1];
for (int i = n / 2; i < n; ++i) {
a[i] *= pw;
pw *= r;
}
fft(a.data() + n / 2, n / 2);
}
// returns [x^k] f(x) / g(x)
// requires LEN(f) < LEN(g) and g[0] != 0
template <typename T>
T fps_div_at(std::vector<T> f, std::vector<T> g, long long k) {
static constexpr FFTRoot<T::get_mod()> fft_root;
static constexpr T INV2 = T(2).inv();
assert(f.size() < g.size() && g[0] != T(0));
if (g.size() == 1) {
return T(0);
}
int n = (int)std::bit_ceil(2 * g.size() - 1);
f.resize(n, T(0));
g.resize(n, T(0));
fft(f);
fft(g);
while (k >= n) {
for (int i = 0; i < n; ++i) {
f[i] *= g[i ^ 1];
}
if (k & 1) {
T p(1);
for (int i = 0; i < n / 2; ++i) {
f[i] = (f[2 * i] - f[2 * i + 1]) * INV2 * p;
p *= fft_root.irate2[__builtin_ctz(~i)];
}
} else {
for (int i = 0; i < n / 2; ++i) {
f[i] = (f[2 * i] + f[2 * i + 1]) * INV2;
}
}
extend_fft(f);
for (int i = 0; i < n / 2; ++i) {
g[i] = g[2 * i] * g[2 * i + 1];
}
extend_fft(g);
k /= 2;
}
ifft(f);
ifft(g);
std::vector<T> inv_g = fps_inv(g);
T ans(0);
for (int i = 0; i <= k; ++i) {
ans += f[i] * inv_g[k - i];
}
return ans;
}
int solve(int d, int64_t k, vector<int> aa, vector<int> rr) {
using M = ModInt<998244353>;
vector<M> a(d);
for (int i = 0; i < d; i++) {
a[i] = aa[i];
}
vector<M> c(d);
for (int i = 0; i < d; i++) {
c[i] = rr[i];
}
vector<M> den(d + 1);
den[0] = M(1);
for (int i = 0; i < d; i++) {
den[i + 1] = -c[i];
}
vector<M> num = convolve(a, den);
num.resize(d);
M ans = fps_div_at(num, den, k);
return ans.val;
}
}
namespace berlekamp_massey {
template<typename T>
std::vector<T> find_recurrence(const std::vector<T> &values) {
if (values.empty())
return {};
std::vector<T> add_option{}, recurrence{};
int add_position = -1;
T add_value = values[1];
for (int i = 0; i < int(values.size()); i++) {
T value = 0;
for (int j = 0; j < int(recurrence.size()); j++)
value += values[i - j - 1] * recurrence[j];
T delta = values[i] - value;
if (delta == 0)
continue;
std::vector<T> new_recurrence;
if (add_position == -1) {
new_recurrence.assign(i + 1, 0);
} else {
new_recurrence = add_option;
std::reverse(new_recurrence.begin(), new_recurrence.end());
new_recurrence.push_back(-1);
for (int it = 0; it < i - add_position - 1; it++)
new_recurrence.push_back(0);
std::reverse(new_recurrence.begin(), new_recurrence.end());
T coeff = -delta / add_value;
for (auto &x : new_recurrence)
x *= coeff;
if (new_recurrence.size() < recurrence.size())
new_recurrence.resize(recurrence.size());
for (int i = 0; i < int(recurrence.size()); i++)
new_recurrence[i] += recurrence[i];
}
if (i - int(recurrence.size()) >= add_position - int(add_option.size()) || add_position == -1) {
add_option = recurrence;
add_position = i;
add_value = delta;
}
recurrence = new_recurrence;
}
return recurrence;
}
template<typename T>
std::vector<T> multiply(const std::vector<T> &first, const std::vector<T> &second) {
// can be replaced with fft multiplication
std::vector<T> prod(max(0, int(first.size() + second.size()) - 1));
for (int i = 0; i < int(first.size()); i++)
for (int j = 0; j < int(second.size()); j++)
prod[i + j] += first[i] * second[j];
return prod;
}
template<typename T>
std::vector<T> find_remainder(std::vector<T> first, const std::vector<T> &second) {
// can be replaced with fft division
if (second.empty())
return {};
assert(second.back() != 0);
while (!first.empty() && first.size() >= second.size()) {
if (first.back() == 0) {
first.pop_back();
continue;
}
T coeff = first.back() / second.back();
for (int i = 0; i < int(second.size()); i++)
first[int(first.size()) - int(second.size()) + i] -= coeff * second[i];
}
return first;
}
template<typename T>
std::vector<T> find_remainder(std::vector<T> recurrence, int64_t k) {
while (!recurrence.empty() && recurrence.back() == 0)
recurrence.pop_back();
std::vector<T> result{1}, value{0, 1};
for (; k; k >>= 1) {
if (k & 1)
result = find_remainder(multiply(result, value), recurrence);
value = find_remainder(multiply(value, value), recurrence);
}
return result;
}
template<typename T>
T find_kth(const std::vector<T> &values, std::vector<T> recurrence, int64_t k) {
std::reverse(recurrence.begin(), recurrence.end());
recurrence.push_back(-1);
std::vector<T> poly = find_remainder(recurrence, k);
T result = 0;
for (int i = 0; i < int(poly.size()); i++)
result += poly[i] * values[i];
return result;
}
} // berlekamp_massey
signed main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
int n, m;
int64_t k;
cin >> n >> m >> k;
k--;
vector g(n, vector<int>(n));
while (m--) {
int v, u;
cin >> v >> u;
v--, u--;
g[v][u] = 1;
g[u][v] = 1;
}
vector dp(n, vector<mint>(n));
for (int j = 1; j < n; j++) {
if (g[0][j]) {
dp[0][j] = 1;
}
}
auto get_ans = [&]() {
mint ans = 0;
for (int i = 0; i < n - 1; i++) {
ans += dp[i][n - 1];
}
return ans;
};
vector<mint> ans;
ans.push_back(get_ans());
vector ndp(n, vector<mint>(n));
vector<mint> sum(n);
while (len(ans) <= k && double(clock()) / CLOCKS_PER_SEC < 2.5 && len(ans) <= 3e4) {
for (auto &v : ndp) {
for (auto &x : v) {
x = 0;
}
}
for (auto &x : sum) {
x = 0;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
sum[j] += dp[i][j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (!g[i][j]) {
continue;
}
ndp[i][j] = sum[i];
ndp[i][j] -= dp[j][i];
}
}
dp.swap(ndp);
ans.push_back(get_ans());
}
if (len(ans) > k) {
cout << ans[k] << '\n';
return 0;
}
// auto res = berlekamp_massey::find_recurrence(ans);
// cout << res.size() << endl;
// for (auto x : res) cout << x << ' '; cout << endl;
// cout << berlekamp_massey::find_kth(ans, res, k) << '\n';
const auto [P, Q] = rational_function_approximation(Poly<mint>(ans.rbegin(), ans.rend()),
Poly<mint>{mint(1)} << ans.size(), ans.size());
const auto res = Q / Poly<mint>{Q.lc()};
vector<int> aa(res.deg()), rr(res.deg());
for (int i = 0; i < res.deg(); i++) {
aa[i] = ans[i].val();
rr[i] = (-res[res.deg() - 1 - i]).val();
}
// cout << res.deg() << endl;
// for (auto x : rr) cout << x << ' '; cout << endl;
// for (auto x : aa) cout << x << ' '; cout << endl;
cout << lol::solve(res.deg(), k, aa, rr) << '\n';
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3692kb
input:
6 8 5 1 2 1 3 2 3 2 4 3 5 4 5 4 6 5 6
output:
2
result:
ok "2"
Test #2:
score: 0
Accepted
time: 1ms
memory: 3776kb
input:
11 11 2023 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 1 11
output:
1
result:
ok "1"
Test #3:
score: 0
Accepted
time: 7ms
memory: 4860kb
input:
7 21 1000000000 1 2 1 3 1 4 1 5 1 6 1 7 2 3 2 4 2 5 2 6 2 7 3 4 3 5 3 6 3 7 4 5 4 6 4 7 5 6 5 7 6 7
output:
405422475
result:
ok "405422475"
Test #4:
score: 0
Accepted
time: 30ms
memory: 4844kb
input:
12 56 78144853 1 2 1 3 1 4 1 6 1 7 1 9 1 10 1 11 1 12 2 4 2 5 2 6 2 8 2 9 2 10 2 11 2 12 3 4 3 5 3 6 3 7 3 8 3 9 3 11 3 12 4 5 4 6 4 7 4 8 4 9 4 10 4 11 4 12 5 6 5 7 5 8 5 9 5 10 5 11 5 12 6 8 6 9 6 10 7 8 7 9 7 11 7 12 8 9 8 10 8 11 8 12 9 10 9 11 9 12 10 11 11 12
output:
843326021
result:
ok "843326021"
Test #5:
score: 0
Accepted
time: 33ms
memory: 4880kb
input:
13 61 268435455 1 2 1 3 1 4 1 5 1 6 1 8 1 9 1 10 1 11 1 12 1 13 2 3 2 4 2 5 2 6 2 7 2 8 2 9 2 12 2 13 3 4 3 5 3 6 3 7 3 8 3 9 3 10 4 6 4 7 4 9 4 12 4 13 5 6 5 7 5 9 5 11 5 13 6 7 6 8 6 9 6 11 6 12 6 13 7 8 7 10 7 11 7 12 8 9 8 10 8 11 8 12 8 13 9 10 9 12 9 13 10 11 10 12 10 13 11 12 11 13 12 13
output:
69651169
result:
ok "69651169"
Test #6:
score: 0
Accepted
time: 40ms
memory: 4856kb
input:
14 79 33554431 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 2 3 2 4 2 5 2 6 2 7 2 8 2 11 2 12 2 14 3 5 3 6 3 7 3 8 3 9 3 10 3 11 3 12 3 13 3 14 4 5 4 6 4 7 4 8 4 9 4 11 4 12 5 6 5 7 5 10 5 11 5 12 5 13 5 14 6 7 6 8 6 9 6 10 6 11 6 12 6 13 6 14 7 8 7 9 7 10 7 11 7 12 7 13 7 14 8 10 8 11 8...
output:
793621538
result:
ok "793621538"
Test #7:
score: 0
Accepted
time: 46ms
memory: 4944kb
input:
15 92 439487671 1 2 1 3 1 5 1 7 1 8 1 9 1 10 1 11 1 13 1 14 1 15 2 3 2 4 2 5 2 6 2 7 2 8 2 9 2 10 2 11 2 12 2 13 2 14 2 15 3 4 3 5 3 6 3 7 3 8 3 9 3 10 3 11 3 12 3 13 3 14 3 15 4 5 4 6 4 7 4 8 4 9 4 10 4 11 4 12 4 13 4 14 4 15 5 7 5 8 5 10 5 11 5 12 5 13 5 14 6 7 6 8 6 9 6 10 6 11 6 12 6 13 6 14 6 1...
output:
196201187
result:
ok "196201187"
Test #8:
score: 0
Accepted
time: 6ms
memory: 4976kb
input:
5 10 230391930 1 2 1 3 1 4 1 5 2 3 2 4 2 5 3 4 3 5 4 5
output:
552614127
result:
ok "552614127"
Test #9:
score: 0
Accepted
time: 7ms
memory: 4776kb
input:
5 8 268435455 1 2 1 3 1 4 2 3 2 4 2 5 3 4 4 5
output:
666456772
result:
ok "666456772"
Test #10:
score: 0
Accepted
time: 12ms
memory: 4860kb
input:
6 13 67108863 1 2 1 3 1 4 1 5 2 4 2 5 2 6 3 4 3 5 3 6 4 5 4 6 5 6
output:
317571510
result:
ok "317571510"
Test #11:
score: 0
Accepted
time: 9ms
memory: 4876kb
input:
7 18 67108863 1 2 1 3 1 4 1 5 1 6 1 7 2 3 2 4 2 5 2 6 2 7 3 5 3 6 4 5 4 6 4 7 5 6 6 7
output:
921436359
result:
ok "921436359"
Test #12:
score: 0
Accepted
time: 24ms
memory: 4928kb
input:
11 43 115349891 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 2 3 2 6 2 7 2 8 2 9 2 11 3 4 3 5 3 8 3 9 3 10 4 5 4 6 4 7 4 8 4 9 4 11 5 6 5 7 5 9 5 10 5 11 6 7 6 9 6 10 6 11 7 8 7 9 7 10 7 11 8 9 8 11 9 10 9 11
output:
853336717
result:
ok "853336717"
Test #13:
score: 0
Accepted
time: 42ms
memory: 4860kb
input:
14 78 758166229 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 2 3 2 4 2 5 2 6 2 7 2 8 2 10 2 11 2 14 3 5 3 6 3 7 3 8 3 9 3 10 3 11 4 5 4 6 4 7 4 8 4 9 4 10 4 11 4 13 4 14 5 6 5 7 5 8 5 9 5 10 5 11 5 13 5 14 6 7 6 8 6 9 6 10 6 11 6 12 6 14 7 8 7 9 7 10 7 11 7 12 7 13 7 14 8 9 8 10 8 11 8 1...
output:
949739691
result:
ok "949739691"
Test #14:
score: 0
Accepted
time: 95ms
memory: 4772kb
input:
52 51 376665160 1 2 1 3 2 4 4 5 5 6 5 7 3 8 5 9 5 10 5 11 6 12 4 13 2 14 6 15 14 16 9 17 8 18 15 19 11 20 9 21 1 22 21 23 3 24 24 25 24 26 10 27 7 28 24 29 16 30 6 31 4 32 5 33 10 34 33 35 32 36 19 37 29 38 18 39 17 40 13 41 39 42 3 43 12 44 34 45 20 46 38 47 27 48 43 49 5 50 6 51 4 52
output:
0
result:
ok "0"
Test #15:
score: 0
Accepted
time: 0ms
memory: 3880kb
input:
29 28 4 1 2 1 3 2 4 1 5 3 6 3 7 6 8 4 9 3 10 6 11 10 12 4 13 3 14 9 15 6 16 14 17 16 18 11 19 19 20 8 21 6 22 18 23 18 24 3 25 2 26 8 27 1 28 8 29
output:
1
result:
ok "1"
Test #16:
score: 0
Accepted
time: 383ms
memory: 4736kb
input:
99 98 33554431 46 94 29 46 29 75 50 75 50 61 6 61 6 10 10 49 38 49 38 86 37 86 37 66 31 66 31 71 41 71 41 67 22 67 22 52 52 62 62 74 74 89 53 89 53 91 69 91 40 69 40 97 45 97 9 45 9 18 18 23 23 25 25 43 43 92 3 92 3 5 5 28 28 58 19 58 17 19 17 80 4 80 4 56 24 56 21 24 1 21 1 95 51 95 36 51 36 96 20 ...
output:
0
result:
ok "0"
Test #17:
score: 0
Accepted
time: 0ms
memory: 3804kb
input:
98 97 2 1 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 2 10 2 11 2 12 2 13 2 14 2 15 2 16 2 17 2 18 2 19 2 20 2 21 2 22 2 23 2 24 2 25 2 26 2 27 2 28 2 29 2 30 2 31 2 32 2 33 2 34 2 35 2 36 2 37 2 38 2 39 2 40 2 41 2 42 2 43 2 44 2 45 2 46 2 47 2 48 2 49 2 50 2 51 2 52 2 53 2 54 2 55 2 56 2 57 2 58 2 59 2 60 2 61 ...
output:
1
result:
ok "1"
Test #18:
score: 0
Accepted
time: 319ms
memory: 5128kb
input:
91 91 68838384 35 46 29 46 29 75 50 75 50 61 6 61 6 10 10 49 38 49 38 86 37 86 37 66 31 66 31 71 41 71 41 67 22 67 22 52 52 62 62 74 74 89 53 89 53 91 69 91 40 69 40 79 45 79 9 45 9 18 18 23 23 25 25 43 12 43 3 12 3 5 5 28 28 58 19 58 17 19 17 80 4 80 4 56 24 56 21 24 1 21 1 64 51 64 36 51 36 47 20 ...
output:
1
result:
ok "1"
Test #19:
score: 0
Accepted
time: 346ms
memory: 5216kb
input:
92 92 860263916 30 45 45 60 60 66 66 78 15 78 9 15 9 14 14 35 35 37 37 85 24 85 24 65 64 65 10 64 10 53 32 53 22 32 22 51 51 80 80 92 77 92 43 77 33 43 33 39 39 82 6 82 2 6 2 88 40 88 40 58 25 58 25 72 72 91 7 91 7 8 8 57 48 57 21 48 21 68 68 79 55 79 12 55 12 38 1 38 1 90 63 90 13 63 13 44 44 54 47...
output:
1
result:
ok "1"
Test #20:
score: 0
Accepted
time: 491ms
memory: 4912kb
input:
91 4095 412854823 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 38 1 39 1 40 1 41 1 42 1 43 1 44 1 45 1 46 1 47 1 48 1 49 1 50 1 51 1 52 1 53 1 54 1 55 1 56 1 57 1 58 1 59 ...
output:
309435713
result:
ok "309435713"
Test #21:
score: 0
Accepted
time: 494ms
memory: 5112kb
input:
92 4186 67108863 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 38 1 39 1 40 1 41 1 42 1 43 1 44 1 45 1 46 1 47 1 48 1 49 1 50 1 51 1 52 1 53 1 54 1 55 1 56 1 57 1 58 1 59 1...
output:
445773689
result:
ok "445773689"
Test #22:
score: 0
Accepted
time: 496ms
memory: 5036kb
input:
93 4278 536870911 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 38 1 39 1 40 1 41 1 42 1 43 1 44 1 45 1 46 1 47 1 48 1 49 1 50 1 51 1 52 1 53 1 54 1 55 1 56 1 57 1 58 1 59 ...
output:
664971360
result:
ok "664971360"
Test #23:
score: 0
Accepted
time: 505ms
memory: 5024kb
input:
94 4371 531304381 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 38 1 39 1 40 1 41 1 42 1 43 1 44 1 45 1 46 1 47 1 48 1 49 1 50 1 51 1 52 1 53 1 54 1 55 1 56 1 57 1 58 1 59 ...
output:
33852961
result:
ok "33852961"
Test #24:
score: 0
Accepted
time: 13ms
memory: 4924kb
input:
10 38 187055368 1 2 1 3 1 5 1 6 1 8 1 9 1 10 2 3 2 4 2 5 2 6 2 7 2 8 2 9 2 10 3 4 3 5 3 6 3 7 3 8 3 9 3 10 4 5 4 6 4 7 4 8 4 9 5 7 5 8 5 9 5 10 6 7 6 8 6 9 6 10 7 8 7 10 8 10
output:
174346166
result:
ok "174346166"
Test #25:
score: 0
Accepted
time: 170ms
memory: 4900kb
input:
31 395 508956048 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 12 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 23 1 24 1 25 1 26 1 27 1 28 1 30 1 31 2 3 2 4 2 5 2 6 2 7 2 8 2 9 2 10 2 11 2 12 2 13 2 14 2 16 2 17 2 18 2 19 2 20 2 22 2 23 2 24 2 25 2 26 2 27 2 28 2 29 2 30 2 31 3 4 3 5 3 7 3 8 3 9 3 10 3 11 3 1...
output:
898454226
result:
ok "898454226"
Test #26:
score: 0
Accepted
time: 362ms
memory: 4896kb
input:
46 843 103688348 1 2 1 3 1 4 1 5 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 33 1 34 1 35 1 36 1 37 1 38 1 41 1 42 1 43 1 44 1 45 2 3 2 4 2 5 2 6 2 7 2 9 2 10 2 11 2 12 2 13 2 14 2 15 2 16 2 18 2 19 2 20 2 22 2 23 2 26 2...
output:
804037438
result:
ok "804037438"
Test #27:
score: 0
Accepted
time: 1088ms
memory: 5136kb
input:
81 2612 536870911 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 21 1 22 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 33 1 34 1 36 1 37 1 38 1 39 1 40 1 41 1 42 1 43 1 44 1 45 1 46 1 47 1 49 1 50 1 51 1 52 1 53 1 55 1 56 1 57 1 58 1 59 1 60 1 61 1 63 1 64 1 65 ...
output:
439960927
result:
ok "439960927"
Test #28:
score: 0
Accepted
time: 1610ms
memory: 5236kb
input:
98 3845 134217727 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 13 1 15 1 16 1 17 1 18 1 20 1 21 1 22 1 23 1 24 1 26 1 27 1 30 1 32 1 33 1 34 1 35 1 38 1 40 1 41 1 42 1 44 1 45 1 46 1 48 1 49 1 50 1 51 1 52 1 53 1 56 1 57 1 58 1 59 1 60 1 61 1 62 1 63 1 64 1 65 1 66 1 67 1 68 1 69 1 71 1 72 1 74 1 75 ...
output:
687576024
result:
ok "687576024"
Test #29:
score: 0
Accepted
time: 251ms
memory: 4896kb
input:
38 559 33554431 1 2 1 3 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 14 1 15 1 16 1 18 1 20 1 21 1 23 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 33 1 34 1 35 1 38 2 4 2 5 2 6 2 8 2 9 2 10 2 11 2 12 2 13 2 14 2 15 2 16 2 18 2 19 2 20 2 21 2 22 2 24 2 25 2 26 2 28 2 29 2 30 2 31 2 32 2 34 3 4 3 5 3 6 3 7 3 8 3 9 3...
output:
245031029
result:
ok "245031029"
Test #30:
score: 0
Accepted
time: 466ms
memory: 4956kb
input:
53 1106 268435455 1 2 1 3 1 4 1 5 1 6 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 33 1 34 1 35 1 36 1 38 1 39 1 40 1 41 1 42 1 43 1 44 1 46 1 47 1 48 1 49 1 50 1 51 1 52 1 53 2 3 2 4 2 5 2 6 2 7 2 9 2 10 2 11 2 13 2 14 ...
output:
437352844
result:
ok "437352844"
Test #31:
score: 0
Accepted
time: 316ms
memory: 4932kb
input:
43 725 710015779 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 14 1 15 1 16 1 18 1 19 1 20 1 23 1 24 1 26 1 27 1 28 1 29 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 39 1 40 1 41 1 42 1 43 2 3 2 4 2 5 2 6 2 7 2 8 2 9 2 10 2 11 2 13 2 14 2 15 2 16 2 17 2 18 2 19 2 20 2 21 2 23 2 24 2 26 2 27 2 29 2 32 2 3...
output:
287707534
result:
ok "287707534"
Test #32:
score: 0
Accepted
time: 708ms
memory: 5092kb
input:
66 1737 67108863 1 2 1 3 1 5 1 6 1 7 1 8 1 9 1 10 1 12 1 13 1 15 1 16 1 17 1 18 1 21 1 22 1 23 1 24 1 25 1 26 1 31 1 32 1 34 1 35 1 36 1 37 1 38 1 39 1 40 1 41 1 42 1 43 1 45 1 46 1 47 1 49 1 50 1 51 1 53 1 54 1 55 1 56 1 57 1 58 1 59 1 60 1 61 1 62 1 63 1 64 1 66 2 4 2 5 2 6 2 7 2 8 2 9 2 10 2 11 2...
output:
655903832
result:
ok "655903832"
Test #33:
score: 0
Accepted
time: 168ms
memory: 4864kb
input:
29 327 815825607 1 2 1 3 1 4 1 5 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 18 1 19 1 20 1 21 1 23 1 24 1 25 1 26 1 27 1 28 1 29 2 3 2 5 2 6 2 7 2 8 2 9 2 10 2 12 2 13 2 14 2 15 2 16 2 17 2 18 2 19 2 21 2 23 2 24 2 25 2 26 2 27 2 28 2 29 3 4 3 6 3 7 3 9 3 10 3 11 3 12 3 13 3 15 3 16 3 17 3 18 3 20 ...
output:
3611745
result:
ok "3611745"
Test #34:
score: 0
Accepted
time: 558ms
memory: 5052kb
input:
100 4950 536870911 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 33 1 34 1 35 1 36 1 37 1 38 1 39 1 40 1 41 1 42 1 43 1 44 1 45 1 46 1 47 1 48 1 49 1 50 1 51 1 52 1 53 1 54 1 55 1 56 1 57 1 58 1 59...
output:
77654284
result:
ok "77654284"
Test #35:
score: 0
Accepted
time: 1621ms
memory: 5304kb
input:
100 3962 536870911 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 12 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 33 1 35 1 36 1 37 1 38 1 39 1 41 1 42 1 43 1 44 1 45 1 46 1 47 1 48 1 49 1 51 1 53 1 54 1 55 1 56 1 57 1 58 1 60 1 61 1 62 1 63 1 64 1 65 1 67...
output:
277610741
result:
ok "277610741"
Test #36:
score: 0
Accepted
time: 1659ms
memory: 5192kb
input:
99 3919 536870911 1 2 1 3 1 4 1 5 1 7 1 9 1 10 1 11 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 23 1 24 1 25 1 27 1 28 1 29 1 32 1 33 1 34 1 36 1 37 1 38 1 40 1 41 1 42 1 43 1 44 1 45 1 46 1 47 1 48 1 49 1 50 1 51 1 52 1 53 1 54 1 56 1 57 1 58 1 59 1 60 1 62 1 63 1 64 1 65 1 66 1 67 1 68 1 70 1 7...
output:
377999899
result:
ok "377999899"
Extra Test:
score: 0
Extra Test Passed