QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#105929#5739. Super Meat BrosmaspyAC ✓4430ms17448kbC++2342.4kb2023-05-16 01:01:442023-05-16 01:01:45

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-05-16 01:01:45]
  • 评测
  • 测评结果:AC
  • 用时:4430ms
  • 内存:17448kb
  • [2023-05-16 01:01:44]
  • 提交

answer

#line 1 "library/my_template.hpp"
#if defined(LOCAL)
#include <my_template_compiled.hpp>
#else
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using u32 = unsigned int;
using u64 = unsigned long long;
using i128 = __int128;

template <class T>
constexpr T infty = 0;
template <>
constexpr int infty<int> = 1'000'000'000;
template <>
constexpr ll infty<ll> = ll(infty<int>) * infty<int> * 2;
template <>
constexpr u32 infty<u32> = infty<int>;
template <>
constexpr u64 infty<u64> = infty<ll>;
template <>
constexpr i128 infty<i128> = i128(infty<ll>) * infty<ll>;
template <>
constexpr double infty<double> = infty<ll>;
template <>
constexpr long double infty<long double> = infty<ll>;

using pi = pair<ll, ll>;
using vi = vector<ll>;
template <class T>
using vc = vector<T>;
template <class T>
using vvc = vector<vc<T>>;
template <class T>
using vvvc = vector<vvc<T>>;
template <class T>
using vvvvc = vector<vvvc<T>>;
template <class T>
using vvvvvc = vector<vvvvc<T>>;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;

#define vv(type, name, h, ...) \
  vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...)   \
  vector<vector<vector<type>>> name( \
      h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)       \
  vector<vector<vector<vector<type>>>> name( \
      a, vector<vector<vector<type>>>(       \
             b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))

// https://trap.jp/post/1224/
#define FOR1(a) for (ll _ = 0; _ < ll(a); ++_)
#define FOR2(i, a) for (ll i = 0; i < ll(a); ++i)
#define FOR3(i, a, b) for (ll i = a; i < ll(b); ++i)
#define FOR4(i, a, b, c) for (ll i = a; i < ll(b); i += (c))
#define FOR1_R(a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR2_R(i, a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR3_R(i, a, b) for (ll i = (b)-1; i >= ll(a); --i)
#define overload4(a, b, c, d, e, ...) e
#define overload3(a, b, c, d, ...) d
#define FOR(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__)
#define FOR_R(...) overload3(__VA_ARGS__, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__)

#define FOR_subset(t, s) \
  for (ll t = (s); t >= 0; t = (t == 0 ? -1 : (t - 1) & (s)))
#define all(x) x.begin(), x.end()
#define len(x) ll(x.size())
#define elif else if

#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second

#define stoi stoll

int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(ll x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }

template <typename T, typename U>
T ceil(T x, U y) {
  return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U>
T floor(T x, U y) {
  return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T, typename U>
pair<T, T> divmod(T x, U y) {
  T q = floor(x, y);
  return {q, x - q * y};
}

template <typename T, typename U>
T SUM(const vector<U> &A) {
  T sum = 0;
  for (auto &&a: A) sum += a;
  return sum;
}

#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) \
  sort(all(x)), x.erase(unique(all(x)), x.end()), x.shrink_to_fit()

template <typename T>
T POP(deque<T> &que) {
  T a = que.front();
  que.pop_front();
  return a;
}
template <typename T>
T POP(pq<T> &que) {
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(pqg<T> &que) {
  assert(!que.empty());
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(vc<T> &que) {
  assert(!que.empty());
  T a = que.back();
  que.pop_back();
  return a;
}

template <typename F>
ll binary_search(F check, ll ok, ll ng, bool check_ok = true) {
  if (check_ok) assert(check(ok));
  while (abs(ok - ng) > 1) {
    auto x = (ng + ok) / 2;
    tie(ok, ng) = (check(x) ? mp(x, ng) : mp(ok, x));
  }
  return ok;
}
template <typename F>
double binary_search_real(F check, double ok, double ng, int iter = 100) {
  FOR(iter) {
    double x = (ok + ng) / 2;
    tie(ok, ng) = (check(x) ? mp(x, ng) : mp(ok, x));
  }
  return (ok + ng) / 2;
}

template <class T, class S>
inline bool chmax(T &a, const S &b) {
  return (a < b ? a = b, 1 : 0);
}
template <class T, class S>
inline bool chmin(T &a, const S &b) {
  return (a > b ? a = b, 1 : 0);
}

// ? は -1
vc<int> s_to_vi(const string &S, char first_char) {
  vc<int> A(S.size());
  FOR(i, S.size()) { A[i] = (S[i] != '?' ? S[i] - first_char : -1); }
  return A;
}

template <typename T, typename U>
vector<T> cumsum(vector<U> &A, int off = 1) {
  int N = A.size();
  vector<T> B(N + 1);
  FOR(i, N) { B[i + 1] = B[i] + A[i]; }
  if (off == 0) B.erase(B.begin());
  return B;
}

// stable sort
template <typename T>
vector<int> argsort(const vector<T> &A) {
  vector<int> ids(len(A));
  iota(all(ids), 0);
  sort(all(ids),
       [&](int i, int j) { return (A[i] == A[j] ? i < j : A[i] < A[j]); });
  return ids;
}

// A[I[0]], A[I[1]], ...
template <typename T>
vc<T> rearrange(const vc<T> &A, const vc<int> &I) {
  vc<T> B(len(I));
  FOR(i, len(I)) B[i] = A[I[i]];
  return B;
}
#endif
#line 1 "library/other/io.hpp"
// based on yosupo's fastio
#include <unistd.h>

namespace fastio {
#define FASTIO
// クラスが read(), print() を持っているかを判定するメタ関数
struct has_write_impl {
  template <class T>
  static auto check(T &&x) -> decltype(x.write(), std::true_type{});

  template <class T>
  static auto check(...) -> std::false_type;
};

template <class T>
class has_write : public decltype(has_write_impl::check<T>(std::declval<T>())) {
};

struct has_read_impl {
  template <class T>
  static auto check(T &&x) -> decltype(x.read(), std::true_type{});

  template <class T>
  static auto check(...) -> std::false_type;
};

template <class T>
class has_read : public decltype(has_read_impl::check<T>(std::declval<T>())) {};

struct Scanner {
  FILE *fp;
  char line[(1 << 15) + 1];
  size_t st = 0, ed = 0;
  void reread() {
    memmove(line, line + st, ed - st);
    ed -= st;
    st = 0;
    ed += fread(line + ed, 1, (1 << 15) - ed, fp);
    line[ed] = '\0';
  }
  bool succ() {
    while (true) {
      if (st == ed) {
        reread();
        if (st == ed) return false;
      }
      while (st != ed && isspace(line[st])) st++;
      if (st != ed) break;
    }
    if (ed - st <= 50) {
      bool sep = false;
      for (size_t i = st; i < ed; i++) {
        if (isspace(line[i])) {
          sep = true;
          break;
        }
      }
      if (!sep) reread();
    }
    return true;
  }
  template <class T, enable_if_t<is_same<T, string>::value, int> = 0>
  bool read_single(T &ref) {
    if (!succ()) return false;
    while (true) {
      size_t sz = 0;
      while (st + sz < ed && !isspace(line[st + sz])) sz++;
      ref.append(line + st, sz);
      st += sz;
      if (!sz || st != ed) break;
      reread();
    }
    return true;
  }
  template <class T, enable_if_t<is_integral<T>::value, int> = 0>
  bool read_single(T &ref) {
    if (!succ()) return false;
    bool neg = false;
    if (line[st] == '-') {
      neg = true;
      st++;
    }
    ref = T(0);
    while (isdigit(line[st])) { ref = 10 * ref + (line[st++] & 0xf); }
    if (neg) ref = -ref;
    return true;
  }
  template <typename T,
            typename enable_if<has_read<T>::value>::type * = nullptr>
  inline bool read_single(T &x) {
    x.read();
    return true;
  }
  bool read_single(double &ref) {
    string s;
    if (!read_single(s)) return false;
    ref = std::stod(s);
    return true;
  }
  bool read_single(char &ref) {
    string s;
    if (!read_single(s) || s.size() != 1) return false;
    ref = s[0];
    return true;
  }
  template <class T>
  bool read_single(vector<T> &ref) {
    for (auto &d: ref) {
      if (!read_single(d)) return false;
    }
    return true;
  }
  template <class T, class U>
  bool read_single(pair<T, U> &p) {
    return (read_single(p.first) && read_single(p.second));
  }
  template <size_t N = 0, typename T>
  void read_single_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
      auto &x = std::get<N>(t);
      read_single(x);
      read_single_tuple<N + 1>(t);
    }
  }
  template <class... T>
  bool read_single(tuple<T...> &tpl) {
    read_single_tuple(tpl);
    return true;
  }
  void read() {}
  template <class H, class... T>
  void read(H &h, T &... t) {
    bool f = read_single(h);
    assert(f);
    read(t...);
  }
  Scanner(FILE *fp) : fp(fp) {}
};

struct Printer {
  Printer(FILE *_fp) : fp(_fp) {}
  ~Printer() { flush(); }

  static constexpr size_t SIZE = 1 << 15;
  FILE *fp;
  char line[SIZE], small[50];
  size_t pos = 0;
  void flush() {
    fwrite(line, 1, pos, fp);
    pos = 0;
  }
  void write(const char val) {
    if (pos == SIZE) flush();
    line[pos++] = val;
  }
  template <class T, enable_if_t<is_integral<T>::value, int> = 0>
  void write(T val) {
    if (pos > (1 << 15) - 50) flush();
    if (val == 0) {
      write('0');
      return;
    }
    if (val < 0) {
      write('-');
      val = -val; // todo min
    }
    size_t len = 0;
    while (val) {
      small[len++] = char(0x30 | (val % 10));
      val /= 10;
    }
    for (size_t i = 0; i < len; i++) { line[pos + i] = small[len - 1 - i]; }
    pos += len;
  }
  void write(const string s) {
    for (char c: s) write(c);
  }
  void write(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++) write(s[i]);
  }
  void write(const double x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << x;
    string s = oss.str();
    write(s);
  }
  void write(const long double x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << x;
    string s = oss.str();
    write(s);
  }
  template <typename T,
            typename enable_if<has_write<T>::value>::type * = nullptr>
  inline void write(T x) {
    x.write();
  }
  template <class T>
  void write(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
      if (i) write(' ');
      write(val[i]);
    }
  }
  template <class T, class U>
  void write(const pair<T, U> val) {
    write(val.first);
    write(' ');
    write(val.second);
  }
  template <size_t N = 0, typename T>
  void write_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
      if constexpr (N > 0) { write(' '); }
      const auto x = std::get<N>(t);
      write(x);
      write_tuple<N + 1>(t);
    }
  }
  template <class... T>
  bool write(tuple<T...> tpl) {
    write_tuple(tpl);
    return true;
  }
  template <class T, size_t S>
  void write(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
      if (i) write(' ');
      write(val[i]);
    }
  }
  void write(i128 val) {
    string s;
    bool negative = 0;
    if (val < 0) {
      negative = 1;
      val = -val;
    }
    while (val) {
      s += '0' + int(val % 10);
      val /= 10;
    }
    if (negative) s += "-";
    reverse(all(s));
    if (len(s) == 0) s = "0";
    write(s);
  }
};
Scanner scanner = Scanner(stdin);
Printer printer = Printer(stdout);
void flush() { printer.flush(); }
void print() { printer.write('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
  printer.write(head);
  if (sizeof...(Tail)) printer.write(' ');
  print(forward<Tail>(tail)...);
}

void read() {}
template <class Head, class... Tail>
void read(Head &head, Tail &... tail) {
  scanner.read(head);
  read(tail...);
}
} // namespace fastio
using fastio::print;
using fastio::flush;
using fastio::read;

#define INT(...)   \
  int __VA_ARGS__; \
  read(__VA_ARGS__)
#define LL(...)   \
  ll __VA_ARGS__; \
  read(__VA_ARGS__)
#define STR(...)      \
  string __VA_ARGS__; \
  read(__VA_ARGS__)
#define CHAR(...)   \
  char __VA_ARGS__; \
  read(__VA_ARGS__)
#define DBL(...)      \
  double __VA_ARGS__; \
  read(__VA_ARGS__)

#define VEC(type, name, size) \
  vector<type> name(size);    \
  read(name)
#define VV(type, name, h, w)                     \
  vector<vector<type>> name(h, vector<type>(w)); \
  read(name)

void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void no(bool t = 1) { yes(!t); }
#line 1 "mod/factorial.hpp"

template <typename mint>
mint inv(int n) {
  static const int mod = mint::get_mod();
  static vector<mint> dat = {0, 1};
  assert(0 <= n);
  if (n >= mod) n %= mod;
  while (len(dat) <= n) {
    int k = len(dat);
    int q = (mod + k - 1) / k;
    dat.eb(dat[k * q - mod] * mint(q));
  }
  return dat[n];
}

template <typename mint>
mint fact(int n) {
  static const int mod = mint::get_mod();
  assert(0 <= n);
  if (n >= mod) return 0;
  static vector<mint> dat = {1, 1};
  while (len(dat) <= n) dat.eb(dat[len(dat) - 1] * mint(len(dat)));
  return dat[n];
}

template <typename mint>
mint fact_inv(int n) {
  static const int mod = mint::get_mod();
  assert(-1 <= n && n < mod);
  static vector<mint> dat = {1, 1};
  if (n == -1) return mint(0);
  while (len(dat) <= n) dat.eb(dat[len(dat) - 1] * inv<mint>(len(dat)));
  return dat[n];
}

template <class mint, class... Ts>
mint fact_invs(Ts... xs) {
  return (mint(1) * ... * fact_inv<mint>(xs));
}

template <typename mint, class Head, class... Tail>
mint multinomial(Head &&head, Tail &&... tail) {
  return fact<mint>(head) * fact_invs<mint>(std::forward<Tail>(tail)...);
}

template <typename mint>
mint C_dense(int n, int k) {
  static vvc<mint> C;
  static int H = 0, W = 0;
  auto calc = [&](int i, int j) -> mint {
    if (i == 0) return (j == 0 ? mint(1) : mint(0));
    return C[i - 1][j] + (j ? C[i - 1][j - 1] : 0);
  };
  if (W <= k) {
    FOR(i, H) {
      C[i].resize(k + 1);
      FOR(j, W, k + 1) { C[i][j] = calc(i, j); }
    }
    W = k + 1;
  }
  if (H <= n) {
    C.resize(n + 1);
    FOR(i, H, n + 1) {
      C[i].resize(W);
      FOR(j, W) { C[i][j] = calc(i, j); }
    }
    H = n + 1;
  }
  return C[n][k];
}

template <typename mint, bool large = false, bool dense = false>
mint C(ll n, ll k) {
  assert(n >= 0);
  if (k < 0 || n < k) return 0;
  if (dense) return C_dense<mint>(n, k);
  if (!large) return multinomial<mint>(n, k, n - k);
  k = min(k, n - k);
  mint x(1);
  FOR(i, k) x *= mint(n - i);
  return x * fact_inv<mint>(k);
}

template <typename mint, bool large = false>
mint C_inv(ll n, ll k) {
  assert(n >= 0);
  assert(0 <= k && k <= n);
  if (!large) return fact_inv<mint>(n) * fact<mint>(k) * fact<mint>(n - k);
  return mint(1) / C<mint, 1>(n, k);
}

// [x^d] (1-x) ^ {-n} の計算
template <typename mint, bool large = false, bool dense = false>
mint C_negative(ll n, ll d) {
  assert(n >= 0);
  if (d < 0) return mint(0);
  if (n == 0) { return (d == 0 ? mint(1) : mint(0)); }
  return C<mint, large, dense>(n + d - 1, d);
}
#line 3 "library/mod/modint.hpp"

template <int mod>
struct modint {
  int val;
  constexpr modint(const ll val = 0) noexcept
      : val(val >= 0 ? val % mod : (mod - (-val) % mod) % mod) {}
  bool operator<(const modint &other) const {
    return val < other.val;
  } // To use std::map
  modint &operator+=(const modint &p) {
    if ((val += p.val) >= mod) val -= mod;
    return *this;
  }
  modint &operator-=(const modint &p) {
    if ((val += mod - p.val) >= mod) val -= mod;
    return *this;
  }
  modint &operator*=(const modint &p) {
    val = (int)(1LL * val * p.val % mod);
    return *this;
  }
  modint &operator/=(const modint &p) {
    *this *= p.inverse();
    return *this;
  }
  modint operator-() const { return modint(-val); }
  modint operator+(const modint &p) const { return modint(*this) += p; }
  modint operator-(const modint &p) const { return modint(*this) -= p; }
  modint operator*(const modint &p) const { return modint(*this) *= p; }
  modint operator/(const modint &p) const { return modint(*this) /= p; }
  bool operator==(const modint &p) const { return val == p.val; }
  bool operator!=(const modint &p) const { return val != p.val; }
  modint inverse() const {
    int a = val, b = mod, u = 1, v = 0, t;
    while (b > 0) {
      t = a / b;
      swap(a -= t * b, b), swap(u -= t * v, v);
    }
    return modint(u);
  }
  modint pow(ll n) const {
    assert(n >= 0);
    modint ret(1), mul(val);
    while (n > 0) {
      if (n & 1) ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }
#ifdef FASTIO
  void write() { fastio::printer.write(val); }
  void read() { fastio::scanner.read(val); }
#endif
  static constexpr int get_mod() { return mod; }
  // (n, r), r は 1 の 2^n 乗根
  static constexpr pair<int, int> ntt_info() {
    if (mod == 167772161) return {25, 17};
    if (mod == 469762049) return {26, 30};
    if (mod == 754974721) return {24, 362};
    if (mod == 880803841) return {23, 211};
    if (mod == 998244353) return {23, 31};
    if (mod == 1045430273) return {20, 363};
    if (mod == 1051721729) return {20, 330};
    if (mod == 1053818881) return {20, 2789};
    return {-1, -1};
  }
};

struct ArbitraryModInt {
  static constexpr bool is_modint = true;
  int val;
  ArbitraryModInt() : val(0) {}
  ArbitraryModInt(int64_t y)
      : val(y >= 0 ? y % get_mod()
                   : (get_mod() - (-y) % get_mod()) % get_mod()) {}
  bool operator<(const ArbitraryModInt &other) const {
    return val < other.val;
  } // To use std::map<ArbitraryModInt, T>
  static int &get_mod() {
    static int mod = 0;
    return mod;
  }
  static void set_mod(int md) { get_mod() = md; }
  ArbitraryModInt &operator+=(const ArbitraryModInt &p) {
    if ((val += p.val) >= get_mod()) val -= get_mod();
    return *this;
  }
  ArbitraryModInt &operator-=(const ArbitraryModInt &p) {
    if ((val += get_mod() - p.val) >= get_mod()) val -= get_mod();
    return *this;
  }
  ArbitraryModInt &operator*=(const ArbitraryModInt &p) {
    long long a = (long long)val * p.val;
    int xh = (int)(a >> 32), xl = (int)a, d, m;
    asm("divl %4; \n\t" : "=a"(d), "=d"(m) : "d"(xh), "a"(xl), "r"(get_mod()));
    val = m;
    return *this;
  }
  ArbitraryModInt &operator/=(const ArbitraryModInt &p) {
    *this *= p.inverse();
    return *this;
  }
  ArbitraryModInt operator-() const { return ArbitraryModInt(get_mod() - val); }
  ArbitraryModInt operator+(const ArbitraryModInt &p) const {
    return ArbitraryModInt(*this) += p;
  }
  ArbitraryModInt operator-(const ArbitraryModInt &p) const {
    return ArbitraryModInt(*this) -= p;
  }
  ArbitraryModInt operator*(const ArbitraryModInt &p) const {
    return ArbitraryModInt(*this) *= p;
  }
  ArbitraryModInt operator/(const ArbitraryModInt &p) const {
    return ArbitraryModInt(*this) /= p;
  }
  bool operator==(const ArbitraryModInt &p) const { return val == p.val; }
  bool operator!=(const ArbitraryModInt &p) const { return val != p.val; }
  ArbitraryModInt inverse() const {
    int a = val, b = get_mod(), u = 1, v = 0, t;
    while (b > 0) {
      t = a / b;
      swap(a -= t * b, b), swap(u -= t * v, v);
    }
    return ArbitraryModInt(u);
  }
  ArbitraryModInt pow(int64_t n) const {
    assert(n >= 0);
    ArbitraryModInt ret(1), mul(val);
    while (n > 0) {
      if (n & 1) ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }
#ifdef FASTIO
  void write() { fastio::printer.write(val); }
  void read() { fastio::scanner.read(val); }
#endif
  static constexpr pair<int, int> ntt_info() { return {-1, -1}; }
};

using modint107 = modint<1000000007>;
using modint998 = modint<998244353>;
using amint = ArbitraryModInt;

struct has_mod_impl {
  template <class T>
  static auto check(T &&x) -> decltype(x.get_mod(), std::true_type{});
  template <class T>
  static auto check(...) -> std::false_type;
};

template <class T>
class has_mod : public decltype(has_mod_impl::check<T>(std::declval<T>())) {};
#line 2 "library/mod/mod_inv.hpp"
// long でも大丈夫
ll mod_inv(ll val, ll mod) {
  val %= mod;
  if (val < 0) val += mod;
  ll a = val, b = mod, u = 1, v = 0, t;
  while (b > 0) {
    t = a / b;
    swap(a -= t * b, b), swap(u -= t * v, v);
  }
  if (u < 0) u += mod;
  return u;
}
#line 1 "library/poly/convolution_naive.hpp"
template <class T>
vector<T> convolution_naive(const vector<T>& a, const vector<T>& b) {
  int n = int(a.size()), m = int(b.size());
  vector<T> ans(n + m - 1);
  if (n < m) {
    FOR(j, m) FOR(i, n) ans[i + j] += a[i] * b[j];
  } else {
    FOR(i, n) FOR(j, m) ans[i + j] += a[i] * b[j];
  }
  return ans;
}
#line 2 "library/poly/ntt.hpp"

template <class mint>
void ntt(vector<mint>& a, bool inverse) {
  static constexpr int rank2 = mint::ntt_info().fi;
  static constexpr int mod = mint::get_mod();
  static_assert(rank2 != -1);
  static array<mint, rank2 + 1> root;
  static array<mint, rank2 + 1> iroot;
  static array<mint, max(0, rank2 - 1)> rate2, irate2;
  static array<mint, max(0, rank2 - 2)> rate3, irate3;
  static bool prepared = 0;
  if (!prepared) {
    prepared = 1;
    root[rank2] = mint::ntt_info().se;
    iroot[rank2] = mint(1) / root[rank2];
    FOR_R(i, rank2) {
      root[i] = root[i + 1] * root[i + 1];
      iroot[i] = iroot[i + 1] * iroot[i + 1];
    }
    mint prod = 1, iprod = 1;
    for (int i = 0; i <= rank2 - 2; i++) {
      rate2[i] = root[i + 2] * prod;
      irate2[i] = iroot[i + 2] * iprod;
      prod *= iroot[i + 2];
      iprod *= root[i + 2];
    }
    prod = 1, iprod = 1;
    for (int i = 0; i <= rank2 - 3; i++) {
      rate3[i] = root[i + 3] * prod;
      irate3[i] = iroot[i + 3] * iprod;
      prod *= iroot[i + 3];
      iprod *= root[i + 3];
    }
  }

  int n = int(a.size());
  int h = topbit(n);
  assert(n == 1 << h);
  if (!inverse) {
    int len = 0;
    while (len < h) {
      if (h - len == 1) {
        int p = 1 << (h - len - 1);
        mint rot = 1;
        FOR(s, 1 << len) {
          int offset = s << (h - len);
          FOR(i, p) {
            auto l = a[i + offset];
            auto r = a[i + offset + p] * rot;
            a[i + offset] = l + r;
            a[i + offset + p] = l - r;
          }
          rot *= rate2[topbit(~s & -~s)];
        }
        len++;
      } else {
        int p = 1 << (h - len - 2);
        mint rot = 1, imag = root[2];
        for (int s = 0; s < (1 << len); s++) {
          mint rot2 = rot * rot;
          mint rot3 = rot2 * rot;
          int offset = s << (h - len);
          for (int i = 0; i < p; i++) {
            u64 mod2 = u64(mod) * mod;
            u64 a0 = a[i + offset].val;
            u64 a1 = u64(a[i + offset + p].val) * rot.val;
            u64 a2 = u64(a[i + offset + 2 * p].val) * rot2.val;
            u64 a3 = u64(a[i + offset + 3 * p].val) * rot3.val;
            u64 a1na3imag = (a1 + mod2 - a3) % mod * imag.val;
            u64 na2 = mod2 - a2;
            a[i + offset] = a0 + a2 + a1 + a3;
            a[i + offset + 1 * p] = a0 + a2 + (2 * mod2 - (a1 + a3));
            a[i + offset + 2 * p] = a0 + na2 + a1na3imag;
            a[i + offset + 3 * p] = a0 + na2 + (mod2 - a1na3imag);
          }
          rot *= rate3[topbit(~s & -~s)];
        }
        len += 2;
      }
    }
  } else {
    mint coef = mint(1) / mint(len(a));
    FOR(i, len(a)) a[i] *= coef;
    int len = h;
    while (len) {
      if (len == 1) {
        int p = 1 << (h - len);
        mint irot = 1;
        FOR(s, 1 << (len - 1)) {
          int offset = s << (h - len + 1);
          FOR(i, p) {
            u64 l = a[i + offset].val;
            u64 r = a[i + offset + p].val;
            a[i + offset] = l + r;
            a[i + offset + p] = (mod + l - r) * irot.val;
          }
          irot *= irate2[topbit(~s & -~s)];
        }
        len--;
      } else {
        int p = 1 << (h - len);
        mint irot = 1, iimag = iroot[2];
        FOR(s, (1 << (len - 2))) {
          mint irot2 = irot * irot;
          mint irot3 = irot2 * irot;
          int offset = s << (h - len + 2);
          for (int i = 0; i < p; i++) {
            u64 a0 = a[i + offset + 0 * p].val;
            u64 a1 = a[i + offset + 1 * p].val;
            u64 a2 = a[i + offset + 2 * p].val;
            u64 a3 = a[i + offset + 3 * p].val;
            u64 x = (mod + a2 - a3) * iimag.val % mod;
            a[i + offset] = a0 + a1 + a2 + a3;
            a[i + offset + 1 * p] = (a0 + mod - a1 + x) * irot.val;
            a[i + offset + 2 * p] = (a0 + a1 + 2 * mod - a2 - a3) * irot2.val;
            a[i + offset + 3 * p] = (a0 + 2 * mod - a1 - x) * irot3.val;
          }
          irot *= irate3[topbit(~s & -~s)];
        }
        len -= 2;
      }
    }
  }
}
#line 1 "library/poly/fft.hpp"
namespace CFFT {
using real = double;

struct C {
  real x, y;

  C() : x(0), y(0) {}

  C(real x, real y) : x(x), y(y) {}
  inline C operator+(const C& c) const { return C(x + c.x, y + c.y); }
  inline C operator-(const C& c) const { return C(x - c.x, y - c.y); }
  inline C operator*(const C& c) const {
    return C(x * c.x - y * c.y, x * c.y + y * c.x);
  }

  inline C conj() const { return C(x, -y); }
};

const real PI = acosl(-1);
int base = 1;
vector<C> rts = {{0, 0}, {1, 0}};
vector<int> rev = {0, 1};

void ensure_base(int nbase) {
  if (nbase <= base) return;
  rev.resize(1 << nbase);
  rts.resize(1 << nbase);
  for (int i = 0; i < (1 << nbase); i++) {
    rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (nbase - 1));
  }
  while (base < nbase) {
    real angle = PI * 2.0 / (1 << (base + 1));
    for (int i = 1 << (base - 1); i < (1 << base); i++) {
      rts[i << 1] = rts[i];
      real angle_i = angle * (2 * i + 1 - (1 << base));
      rts[(i << 1) + 1] = C(cos(angle_i), sin(angle_i));
    }
    ++base;
  }
}

void fft(vector<C>& a, int n) {
  assert((n & (n - 1)) == 0);
  int zeros = __builtin_ctz(n);
  ensure_base(zeros);
  int shift = base - zeros;
  for (int i = 0; i < n; i++) {
    if (i < (rev[i] >> shift)) { swap(a[i], a[rev[i] >> shift]); }
  }
  for (int k = 1; k < n; k <<= 1) {
    for (int i = 0; i < n; i += 2 * k) {
      for (int j = 0; j < k; j++) {
        C z = a[i + j + k] * rts[j + k];
        a[i + j + k] = a[i + j] - z;
        a[i + j] = a[i + j] + z;
      }
    }
  }
}
} // namespace CFFT
#line 7 "library/poly/convolution.hpp"

template <class mint>
vector<mint> convolution_ntt(vector<mint> a, vector<mint> b) {
  int n = int(a.size()), m = int(b.size());
  int sz = 1;
  while (sz < n + m - 1) sz *= 2;

  // sz = 2^k のときの高速化。分割統治的なやつで損しまくるので。
  if ((n + m - 3) <= sz / 2) {
    auto a_last = a.back(), b_last = b.back();
    a.pop_back(), b.pop_back();
    auto c = convolution(a, b);
    c.resize(n + m - 1);
    c[n + m - 2] = a_last * b_last;
    FOR(i, len(a)) c[i + len(b)] += a[i] * b_last;
    FOR(i, len(b)) c[i + len(a)] += b[i] * a_last;
    return c;
  }

  a.resize(sz), b.resize(sz);
  bool same = a == b;
  ntt(a, 0);
  if (same) {
    b = a;
  } else {
    ntt(b, 0);
  }
  FOR(i, sz) a[i] *= b[i];
  ntt(a, 1);
  a.resize(n + m - 1);
  return a;
}

template <typename mint>
vector<mint> convolution_garner(const vector<mint>& a, const vector<mint>& b) {
  int n = len(a), m = len(b);
  if (!n || !m) return {};
  static const long long nttprimes[] = {754974721, 167772161, 469762049};
  using mint0 = modint<754974721>;
  using mint1 = modint<167772161>;
  using mint2 = modint<469762049>;
  vc<mint0> a0(n), b0(m);
  vc<mint1> a1(n), b1(m);
  vc<mint2> a2(n), b2(m);
  FOR(i, n) a0[i] = a[i].val, a1[i] = a[i].val, a2[i] = a[i].val;
  FOR(i, m) b0[i] = b[i].val, b1[i] = b[i].val, b2[i] = b[i].val;
  auto c0 = convolution_ntt<mint0>(a0, b0);
  auto c1 = convolution_ntt<mint1>(a1, b1);
  auto c2 = convolution_ntt<mint2>(a2, b2);
  static const long long m01 = 1LL * nttprimes[0] * nttprimes[1];
  static const long long m0_inv_m1 = mint1(nttprimes[0]).inverse().val;
  static const long long m01_inv_m2 = mint2(m01).inverse().val;
  static const int mod = mint::get_mod();
  auto garner = [&](mint0 x0, mint1 x1, mint2 x2) -> mint {
    int r0 = x0.val, r1 = x1.val, r2 = x2.val;
    int v1 = (m0_inv_m1 * (r1 + nttprimes[1] - r0)) % nttprimes[1];
    auto v2 = (mint2(r2) - r0 - mint2(nttprimes[0]) * v1) * mint2(m01_inv_m2);
    return mint(r0 + 1LL * nttprimes[0] * v1 + m01 % mod * v2.val);
  };
  vc<mint> c(len(c0));
  FOR(i, len(c)) c[i] = garner(c0[i], c1[i], c2[i]);
  return c;
}

template <typename R>
vc<double> convolution_fft(const vc<R>& a, const vc<R>& b) {
  using C = CFFT::C;
  int need = (int)a.size() + (int)b.size() - 1;
  int nbase = 1;
  while ((1 << nbase) < need) nbase++;
  CFFT::ensure_base(nbase);
  int sz = 1 << nbase;
  vector<C> fa(sz);
  for (int i = 0; i < sz; i++) {
    int x = (i < (int)a.size() ? a[i] : 0);
    int y = (i < (int)b.size() ? b[i] : 0);
    fa[i] = C(x, y);
  }
  CFFT::fft(fa, sz);
  C r(0, -0.25 / (sz >> 1)), s(0, 1), t(0.5, 0);
  for (int i = 0; i <= (sz >> 1); i++) {
    int j = (sz - i) & (sz - 1);
    C z = (fa[j] * fa[j] - (fa[i] * fa[i]).conj()) * r;
    fa[j] = (fa[i] * fa[i] - (fa[j] * fa[j]).conj()) * r;
    fa[i] = z;
  }
  for (int i = 0; i < (sz >> 1); i++) {
    C A0 = (fa[i] + fa[i + (sz >> 1)]) * t;
    C A1 = (fa[i] - fa[i + (sz >> 1)]) * t * CFFT::rts[(sz >> 1) + i];
    fa[i] = A0 + A1 * s;
  }
  CFFT::fft(fa, sz >> 1);
  vector<double> ret(need);
  for (int i = 0; i < need; i++) {
    ret[i] = (i & 1 ? fa[i >> 1].y : fa[i >> 1].x);
  }
  return ret;
}

vector<ll> convolution(const vector<ll>& a, const vector<ll>& b) {
  int n = len(a), m = len(b);
  if (!n || !m) return {};
  if (min(n, m) <= 60) return convolution_naive(a, b);
  ll abs_sum_a = 0, abs_sum_b = 0;
  ll LIM = 1e15;
  FOR(i, n) abs_sum_a = min(LIM, abs_sum_a + abs(a[i]));
  FOR(i, n) abs_sum_b = min(LIM, abs_sum_b + abs(b[i]));
  if (i128(abs_sum_a) * abs_sum_b < 1e15) {
    vc<double> c = convolution_fft<ll>(a, b);
    vc<ll> res(len(c));
    FOR(i, len(c)) res[i] = ll(floor(c[i] + .5));
    return res;
  }

  static constexpr unsigned long long MOD1 = 754974721; // 2^24
  static constexpr unsigned long long MOD2 = 167772161; // 2^25
  static constexpr unsigned long long MOD3 = 469762049; // 2^26
  static constexpr unsigned long long M2M3 = MOD2 * MOD3;
  static constexpr unsigned long long M1M3 = MOD1 * MOD3;
  static constexpr unsigned long long M1M2 = MOD1 * MOD2;
  static constexpr unsigned long long M1M2M3 = MOD1 * MOD2 * MOD3;

  static const unsigned long long i1 = mod_inv(MOD2 * MOD3, MOD1);
  static const unsigned long long i2 = mod_inv(MOD1 * MOD3, MOD2);
  static const unsigned long long i3 = mod_inv(MOD1 * MOD2, MOD3);

  using mint1 = modint<MOD1>;
  using mint2 = modint<MOD2>;
  using mint3 = modint<MOD3>;

  vc<mint1> a1(n), b1(m);
  vc<mint2> a2(n), b2(m);
  vc<mint3> a3(n), b3(m);
  FOR(i, n) a1[i] = a[i], a2[i] = a[i], a3[i] = a[i];
  FOR(i, m) b1[i] = b[i], b2[i] = b[i], b3[i] = b[i];

  auto c1 = convolution_ntt<mint1>(a1, b1);
  auto c2 = convolution_ntt<mint2>(a2, b2);
  auto c3 = convolution_ntt<mint3>(a3, b3);

  vc<ll> c(n + m - 1);
  FOR(i, n + m - 1) {
    u64 x = 0;
    x += (c1[i].val * i1) % MOD1 * M2M3;
    x += (c2[i].val * i2) % MOD2 * M1M3;
    x += (c3[i].val * i3) % MOD3 * M1M2;
    ll diff = c1[i].val - ((long long)(x) % (long long)(MOD1));
    if (diff < 0) diff += MOD1;
    static constexpr unsigned long long offset[5]
        = {0, 0, M1M2M3, 2 * M1M2M3, 3 * M1M2M3};
    x -= offset[diff % 5];
    c[i] = x;
  }
  return c;
}

template <typename mint>
enable_if_t<is_same<mint, modint998>::value, vc<mint>> convolution(
    const vc<mint>& a, const vc<mint>& b) {
  int n = len(a), m = len(b);
  if (!n || !m) return {};
  if (min(n, m) <= 60) return convolution_naive(a, b);
  return convolution_ntt(a, b);
}

template <typename mint>
enable_if_t<!is_same<mint, modint998>::value, vc<mint>> convolution(
    const vc<mint>& a, const vc<mint>& b) {
  int n = len(a), m = len(b);
  if (!n || !m) return {};
  if (min(n, m) <= 60) return convolution_naive(a, b);
  return convolution_garner(a, b);
}
#line 2 "library/poly/coef_of_rational_fps.hpp"

template <typename mint>
mint coef_of_rational_fps(vector<mint> A, vector<mint> B, ll N) {
  if (len(A) == 0) return 0;
  assert(len(A) < len(B));
  while (len(A) + 1 < len(B)) A.eb(0);
  assert(B[0] == mint(1));
  assert(len(B) == len(A) + 1);
  while (N) {
    vc<mint> B1 = B;
    FOR(i, len(B1)) if (i & 1) B1[i] = -B1[i];
    A = convolution(A, B1);
    B = convolution(B, B1);
    FOR(i, len(B1)) B[i] = B[2 * i];
    if (N & 1) {
      FOR(i, len(B1) - 1) A[i] = A[2 * i | 1];
    } else {
      FOR(i, len(B1) - 1) A[i] = A[2 * i];
    }
    A.resize(len(B1) - 1);
    B.resize(len(B1));
    N /= 2;
  }
  return A[0];
}
#line 2 "library/poly/fps_div.hpp"

#line 2 "library/poly/count_terms.hpp"
template<typename mint>
int count_terms(const vc<mint>& f){
  int t = 0;
  FOR(i, len(f)) if(f[i] != mint(0)) ++t;
  return t;
}
#line 4 "library/poly/fps_inv.hpp"

template <typename mint>
vc<mint> fps_inv_sparse(const vc<mint>& f) {
  assert(f[0] != mint(0));
  int N = len(f);
  vc<pair<int, mint>> dat;
  FOR3(i, 1, N) if (f[i] != mint(0)) dat.eb(i, f[i]);
  vc<mint> g(N);
  mint g0 = mint(1) / f[0];
  g[0] = g0;
  FOR3(n, 1, N) {
    mint rhs = 0;
    for (auto&& [k, fk]: dat) {
      if (k > n) break;
      rhs -= fk * g[n - k];
    }
    g[n] = rhs * g0;
  }
  return g;
}

template <typename mint>
enable_if_t<is_same<mint, modint998>::value, vc<mint>> fps_inv_dense(
    const vc<mint>& F) {
  assert(F[0] != mint(0));
  vc<mint> G = {mint(1) / F[0]};
  G.reserve(len(F));
  ll N = len(F), n = 1;
  while (n < N) {
    vc<mint> f(2 * n), g(2 * n);
    FOR(i, min(N, 2 * n)) f[i] = F[i];
    FOR(i, n) g[i] = G[i];
    ntt(f, false);
    ntt(g, false);
    FOR(i, 2 * n) f[i] *= g[i];
    ntt(f, true);
    FOR(i, n) f[i] = 0;
    ntt(f, false);
    FOR(i, 2 * n) f[i] *= g[i];
    ntt(f, true);
    FOR3(i, n, 2 * n) G.eb(f[i] * mint(-1));
    n *= 2;
  }
  G.resize(N);
  return G;
}

template <typename mint>
enable_if_t<!is_same<mint, modint998>::value, vc<mint>> fps_inv_dense(
    const vc<mint>& F) {
  int N = len(F);
  assert(F[0] != mint(0));
  vc<mint> R = {mint(1) / F[0]};
  vc<mint> p;
  int m = 1;
  while (m < N) {
    p = convolution(R, R);
    p.resize(m + m);
    vc<mint> f = {F.begin(), F.begin() + min(m + m, N)};
    p = convolution(p, f);
    R.resize(m + m);
    FOR(i, m + m) R[i] = R[i] + R[i] - p[i];
    m += m;
  }
  R.resize(N);
  return R;
}


template <typename mint>
enable_if_t<is_same<mint, modint998>::value, vc<mint>> fps_inv(
    const vc<mint>& f) {
  if (count_terms(f) <= 200) return fps_inv_sparse<mint>(f);
  return fps_inv_dense<mint>(f);
}

template <typename mint>
enable_if_t<!is_same<mint, modint998>::value, vc<mint>> fps_inv(
    const vc<mint>& f) {
  if (count_terms(f) <= 700) return fps_inv_sparse<mint>(f);
  return fps_inv_dense<mint>(f);
}
#line 5 "library/poly/fps_div.hpp"

// f/g. f の長さで出力される.
template <typename mint, bool SPARSE = false>
vc<mint> fps_div(vc<mint> f, vc<mint> g) {
  if (SPARSE || count_terms(g) < 200) return fps_div_sparse(f, g);
  int n = len(f);
  g.resize(n);
  g = fps_inv<mint>(g);
  f = convolution(f, g);
  f.resize(n);
  return f;
}

// f/g ただし g は sparse
template <typename mint>
vc<mint> fps_div_sparse(vc<mint> f, vc<mint>& g) {
  if (g[0] != mint(1)) {
    mint cf = g[0].inverse();
    for (auto&& x: f) x *= cf;
    for (auto&& x: g) x *= cf;
  }

  vc<pair<int, mint>> dat;
  FOR(i, 1, len(g)) if (g[i] != mint(0)) dat.eb(i, -g[i]);
  FOR(i, len(f)) {
    for (auto&& [j, x]: dat) {
      if (i >= j) f[i] += x * f[i - j];
    }
  }
  return f;
}
#line 2 "library/poly/sum_of_power_of_roots.hpp"

// f = prod(1-a_ix) のとき、g[k] = sum_i a_i^k となる g の [0, LIM] を返す
template <typename mint>
vc<mint> sum_of_power_of_roots(vc<mint>& f, int LIM) {
  const int n = len(f) - 1;
  // n - xf'/f
  vc<mint> g(n + 1);
  FOR(i, n + 1) g[i] = mint(n - i) * f[i];
  g.resize(LIM + 1);
  return fps_div(g, f);
}
#line 2 "library/poly/integrate.hpp"

template <typename mint>
vc<mint> integrate(const vc<mint>& f) {
  vc<mint> g(len(f) + 1);
  FOR3(i, 1, len(g)) g[i] = f[i - 1] * inv<mint>(i);
  return g;
}
#line 2 "library/poly/differentiate.hpp"

template <typename mint>
vc<mint> differentiate(const vc<mint>& f) {
  if (len(f) <= 1) return {};
  vc<mint> g(len(f) - 1);
  FOR(i, len(g)) g[i] = f[i + 1] * mint(i + 1);
  return g;
}
#line 6 "library/poly/fps_exp.hpp"

template <typename mint>
enable_if_t<is_same<mint, modint998>::value, vc<mint>> fps_exp(vc<mint>& f) {
  if (count_terms(f) <= 300) return fps_exp_sparse(f);
  return fps_exp_dense(f);
}

template <typename mint>
enable_if_t<!is_same<mint, modint998>::value, vc<mint>> fps_exp(vc<mint>& f) {
  if (count_terms(f) <= 1000) return fps_exp_sparse(f);
  return fps_exp_dense(f);
}

template <typename mint>
vc<mint> fps_exp_sparse(vc<mint>& f) {
  if (len(f) == 0) return {mint(1)};
  assert(f[0] == 0);
  int N = len(f);
  // df を持たせる
  vc<pair<int, mint>> dat;
  FOR(i, 1, N) if (f[i] != mint(0)) dat.eb(i - 1, mint(i) * f[i]);
  vc<mint> F(N);
  F[0] = 1;
  FOR(n, 1, N) {
    mint rhs = 0;
    for (auto&& [k, fk]: dat) {
      if (k > n - 1) break;
      rhs += fk * F[n - 1 - k];
    }
    F[n] = rhs * inv<mint>(n);
  }
  return F;
}

template <typename mint>
enable_if_t<!is_same<mint, modint998>::value, vc<mint>> fps_exp_dense(
    vc<mint> h) {
  const int L = len(h);
  assert(L > 0 && h[0] == mint(0));
  int LOG = 0;
  while (1 << LOG < L) ++LOG;
  h.resize(1 << LOG);
  auto dh = differentiate(h);
  vc<mint> f = {1}, g = {1};
  int m = 1;

  vc<mint> p;

  FOR(LOG) {
    p = convolution(f, g);
    p.resize(m);
    p = convolution(p, g);
    p.resize(m);
    g.resize(m);
    FOR(i, m) g[i] += g[i] - p[i];
    p = {dh.begin(), dh.begin() + m - 1};
    p = convolution(f, p);
    p.resize(m + m - 1);
    FOR(i, m + m - 1) p[i] = -p[i];
    FOR(i, m - 1) p[i] += mint(i + 1) * f[i + 1];
    p = convolution(p, g);

    p.resize(m + m - 1);
    FOR(i, m - 1) p[i] += dh[i];
    p = integrate(p);
    FOR(i, m + m) p[i] = h[i] - p[i];
    p[0] += mint(1);
    f = convolution(f, p);
    f.resize(m + m);
    m += m;
  }
  f.resize(L);
  return f;
}

// ntt 素数専用実装。長さ n の FFT を利用して 2n の FFT
// を行うなどの高速化をしている。
template <typename mint>
enable_if_t<is_same<mint, modint998>::value, vc<mint>> fps_exp_dense(
    vc<mint>& f) {
  const int n = len(f);
  assert(n > 0 && f[0] == mint(0));
  vc<mint> b = {1, (1 < n ? f[1] : 0)};
  vc<mint> c = {1}, z1, z2 = {1, 1};
  while (len(b) < n) {
    int m = len(b);
    auto y = b;
    y.resize(2 * m);
    ntt(y, 0);
    z1 = z2;
    vc<mint> z(m);
    FOR(i, m) z[i] = y[i] * z1[i];
    ntt(z, 1);
    FOR(i, m / 2) z[i] = 0;
    ntt(z, 0);
    FOR(i, m) z[i] *= -z1[i];
    ntt(z, 1);
    c.insert(c.end(), z.begin() + m / 2, z.end());
    z2 = c;
    z2.resize(2 * m);
    ntt(z2, 0);

    vc<mint> x(f.begin(), f.begin() + m);
    FOR(i, len(x) - 1) x[i] = x[i + 1] * mint(i + 1);
    x.back() = 0;
    ntt(x, 0);
    FOR(i, m) x[i] *= y[i];
    ntt(x, 1);

    FOR(i, m - 1) x[i] -= b[i + 1] * mint(i + 1);

    x.resize(m + m);
    FOR(i, m - 1) x[m + i] = x[i], x[i] = 0;
    ntt(x, 0);
    FOR(i, m + m) x[i] *= z2[i];
    ntt(x, 1);
    FOR_R(i, len(x) - 1) x[i + 1] = x[i] * inv<mint>(i + 1);
    x[0] = 0;

    FOR3(i, m, min(n, m + m)) x[i] += f[i];
    FOR(i, m) x[i] = 0;
    ntt(x, 0);
    FOR(i, m + m) x[i] *= y[i];
    ntt(x, 1);
    b.insert(b.end(), x.begin() + m, x.end());
  }
  b.resize(n);
  return b;
}
#line 3 "library/poly/composed_sum.hpp"

// https://codeforces.com/blog/entry/103136
// f(x) = prod(1-a_i x), g(x) = prod(1-b_j x) のとき
// prod_{i,j} (1-(a_i+b_j)x) を計算する。
template <typename mint>
vc<mint> composed_sum(vc<mint> f, vc<mint> g) {
  int n = len(f) - 1, m = len(g) - 1;
  vc<mint> A = sum_of_power_of_roots(f, n * m);
  vc<mint> B = sum_of_power_of_roots(g, n * m);
  FOR(i, n * m + 1) A[i] *= fact_inv<mint>(i), B[i] *= fact_inv<mint>(i);
  A = convolution(A, B);
  A.resize(n * m + 1);
  FOR(i, n * m + 1) A[i] *= fact<mint>(i);
  FOR(i, len(A)) A[i] = -A[i];
  A[0] += mint(n * m);
  // A.erase(A.begin()); -> f'/f = (log f)'
  FOR(i, 1, n * m + 1) A[i] *= inv<mint>(i);
  return fps_exp(A);
}
#line 6 "main.cpp"

using mint = modint<1'000'000'009>;
using poly = vc<mint>;

void solve() {
  LL(N, M);
  poly f(N + 1), g(N + 1);
  f[0] = g[0] = 1;
  FOR(i, 1, N + 1) {
    INT(x);
    f[i] = -x;
  }
  FOR(i, 1, N + 1) {
    INT(x);
    g[i] = -x;
  }

  poly A = composed_sum(f, g);

  // 数列の計算
  f.resize(N * N + 1);
  g.resize(N * N + 1);
  f = fps_inv(f);
  g = fps_inv(g);
  FOR(i, N * N + 1) f[i] *= fact_inv<mint>(i);
  FOR(i, N * N + 1) g[i] *= fact_inv<mint>(i);
  f = convolution(f, g);
  f.resize(N * N + 1);
  FOR(i, N * N + 1) f[i] *= fact<mint>(i);
  // print(f);
  f = convolution(f, A);
  f.resize(len(A) - 1);
  mint ANS = coef_of_rational_fps(f, A, M);
  print(ANS);
}

signed main() {
  solve();
  return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 3424kb

input:

2 3
1 1
1 1

output:

18

result:

ok 1 number(s): "18"

Test #2:

score: 0
Accepted
time: 1ms
memory: 3568kb

input:

3 4
1 2 3
1 3 2

output:

180

result:

ok 1 number(s): "180"

Test #3:

score: 0
Accepted
time: 2ms
memory: 3572kb

input:

2 10000
1 1
1 1

output:

219175682

result:

ok 1 number(s): "219175682"

Test #4:

score: 0
Accepted
time: 2ms
memory: 3420kb

input:

3 10000
1 2 3
1 3 2

output:

22506633

result:

ok 1 number(s): "22506633"

Test #5:

score: 0
Accepted
time: 0ms
memory: 3568kb

input:

2 100000
1 1
1 1

output:

545932818

result:

ok 1 number(s): "545932818"

Test #6:

score: 0
Accepted
time: 0ms
memory: 3568kb

input:

3 100000
1 2 3
1 3 2

output:

57531357

result:

ok 1 number(s): "57531357"

Test #7:

score: 0
Accepted
time: 0ms
memory: 3456kb

input:

2 1000000
1 1
1 1

output:

573543093

result:

ok 1 number(s): "573543093"

Test #8:

score: 0
Accepted
time: 2ms
memory: 3572kb

input:

3 1000000
1 2 3
1 3 2

output:

403805847

result:

ok 1 number(s): "403805847"

Test #9:

score: 0
Accepted
time: 133ms
memory: 4644kb

input:

100 10
611820018 75283856 260526347 643767967 631268284 65648470 256718930 106368182 843661377 781313189 595194538 910990296 902258405 714186458 994234477 224492449 18296975 46262610 20991790 104288095 566832326 611425812 406579987 77488677 292658024 472980409 639810931 869525405 785145 7334819 9037...

output:

398533280

result:

ok 1 number(s): "398533280"

Test #10:

score: 0
Accepted
time: 212ms
memory: 4740kb

input:

100 1000
337861296 954983610 933984767 158413395 236083015 753884779 480227722 932008977 222135711 538427797 248038326 483405605 988416942 772990315 109612622 13993552 741972144 431449344 885517243 122926909 624917994 844993934 728622505 562105730 55499197 550328547 339918311 264032815 950626134 179...

output:

73138730

result:

ok 1 number(s): "73138730"

Test #11:

score: 0
Accepted
time: 347ms
memory: 4640kb

input:

100 1000000
903000973 111290548 476765164 551975212 417263983 767801442 332671705 278870842 201796633 763068216 960266344 26482099 425400417 95404984 465717382 564861093 884664057 821929061 592534023 30343744 936134428 561670930 15703251 993624219 870390001 723109936 981318197 656667259 663611325 79...

output:

184586019

result:

ok 1 number(s): "184586019"

Test #12:

score: 0
Accepted
time: 490ms
memory: 4668kb

input:

100 1000000000
604297456 257710428 680778188 39374726 220956130 149356685 838936858 237228921 460651102 14915933 281581197 546327552 891296342 578540918 257819754 952356650 464523259 475942266 855600625 501203770 866723687 956420345 653224524 350671741 193934342 737912261 157584420 514316163 5731646...

output:

319681565

result:

ok 1 number(s): "319681565"

Test #13:

score: 0
Accepted
time: 81ms
memory: 3620kb

input:

47 939103
460209796 923769396 497130455 808750267 18580352 834685802 844939762 655958719 739484445 425067482 799235401 220463915 346712582 882586918 650792581 69525904 386758289 448868866 132258056 596695126 476338507 436189171 608073202 431881768 654354303 965133883 322147241 729417140 303007941 43...

output:

697877594

result:

ok 1 number(s): "697877594"

Test #14:

score: 0
Accepted
time: 2ms
memory: 3572kb

input:

5 20320
382406383 333353114 214385221 941605706 957498024
619083842 292772465 335037867 449241457 284312462

output:

648153718

result:

ok 1 number(s): "648153718"

Test #15:

score: 0
Accepted
time: 2ms
memory: 3584kb

input:

10 203
113356422 444048748 334760365 168456429 484325461 304651414 551964556 490305389 320866640 344214227
59919841 828724485 840698445 104730082 572733049 659837626 200222587 316651460 461116205 929846700

output:

860154954

result:

ok 1 number(s): "860154954"

Test #16:

score: 0
Accepted
time: 280ms
memory: 4808kb

input:

100 23203
590215812 330919503 361804049 160841393 202577205 767474814 261396779 534556107 11546512 315928375 548186686 418841505 971313703 728695556 991214364 553240798 294967304 944071947 960112453 266119259 515272798 476117665 854261275 247679517 137587630 103865755 561276374 970920554 9978160 549...

output:

319899104

result:

ok 1 number(s): "319899104"

Test #17:

score: 0
Accepted
time: 112ms
memory: 3816kb

input:

47 1000000000
661236701 626011023 653401016 269507301 947858324 488679806 682307210 795514627 747127946 933364412 126186059 532060957 912405701 875433550 878553905 363499560 534441266 584528443 703237317 73856741 96530866 645865395 853378035 916787403 685813713 118694785 912869318 420101396 63662492...

output:

975440921

result:

ok 1 number(s): "975440921"

Test #18:

score: 0
Accepted
time: 270ms
memory: 6564kb

input:

147 10
462565524 147218320 961380299 517841640 474426942 690678806 708345902 138526412 594824170 711085626 400440944 547048987 257456629 858639492 731548623 743813006 821987881 212909550 986929898 302432282 797126565 348883326 723121207 65669843 523779740 462686631 179539669 863701865 324988545 8236...

output:

842067007

result:

ok 1 number(s): "842067007"

Test #19:

score: 0
Accepted
time: 1103ms
memory: 11004kb

input:

250 1000
359444936 577808352 826049210 937279560 968237772 846436826 63317947 327295422 805344944 972799416 11317310 147013950 783864555 646400672 181338678 200051004 380780464 782975995 907350103 984833619 119607074 682306803 697289898 147681694 652404823 348889915 901738893 696974445 693347094 616...

output:

441591881

result:

ok 1 number(s): "441591881"

Test #20:

score: 0
Accepted
time: 1620ms
memory: 9808kb

input:

200 1000000
874654868 716961475 190056783 217613512 270419311 928606069 110795081 797619047 5066043 622162200 233468286 849682819 932605405 421878748 971561346 522911058 820676673 541104759 868007035 915383864 505494377 249870500 843072321 537442117 621304223 279155014 364150264 753394165 586053537 ...

output:

718830226

result:

ok 1 number(s): "718830226"

Test #21:

score: 0
Accepted
time: 2153ms
memory: 9120kb

input:

190 1000000000
292432717 113243080 782850858 172875356 666459177 694100208 895717171 654232213 811149478 692945443 132670383 501884040 952942129 647574489 801625042 7020933 497251380 57436006 898832679 504715288 374768882 690448784 733992082 836263798 169618991 932677069 868515629 488357250 6225605 ...

output:

262821982

result:

ok 1 number(s): "262821982"

Test #22:

score: 0
Accepted
time: 1416ms
memory: 17360kb

input:

300 10
141416754 840193279 939495438 894074444 357961599 893355088 946771006 468551335 988010195 578425753 45582485 678562805 842752189 299012071 877195300 942962308 312940913 48091926 593525589 431117014 585154959 534766048 914518145 306770747 91708675 676599371 136242034 913227941 655846387 546182...

output:

477817221

result:

ok 1 number(s): "477817221"

Test #23:

score: 0
Accepted
time: 2108ms
memory: 17448kb

input:

300 1000
881842413 86529938 693226698 20757197 164509906 310379730 597581323 380048694 772704893 160215562 406792873 97226450 513243503 324045599 972495119 257440375 826958761 280401032 425640175 326986758 420258228 298452017 710062261 224951134 491316417 407531361 26721586 472379648 484051640 16798...

output:

732490438

result:

ok 1 number(s): "732490438"

Test #24:

score: 0
Accepted
time: 3276ms
memory: 17344kb

input:

300 1000000
100579760 892289966 263679968 936720216 747697319 399346310 126202533 776869874 580862239 418953789 573536832 409884862 171308486 98937954 131377655 991658975 439071483 512301561 944105267 932299071 894863189 263184189 66678588 477820447 34975336 982457276 71778919 387114327 308627278 20...

output:

678269002

result:

ok 1 number(s): "678269002"

Test #25:

score: 0
Accepted
time: 4430ms
memory: 17356kb

input:

300 1000000000
844189155 306246728 764486702 296212354 682237724 995426531 484985870 919411723 19081297 425060640 679557693 229668380 370315094 453252907 409487440 383346311 304432744 706524934 456058788 261585079 888251458 726586849 720010611 433565812 778508674 751679601 496382059 474420983 254876...

output:

255690783

result:

ok 1 number(s): "255690783"