QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#683956#9526. Subsequence CountingmaspyAC ✓180ms53916kbC++2326.9kb2024-10-28 04:53:282024-10-28 04:53:29

Judging History

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

  • [2024-10-28 04:53:29]
  • 评测
  • 测评结果:AC
  • 用时:180ms
  • 内存:53916kb
  • [2024-10-28 04:53:28]
  • 提交

answer

#line 1 "/home/maspy/compro/library/my_template.hpp"
#if defined(LOCAL)
#include <my_template_compiled.hpp>
#else

// https://codeforces.com/blog/entry/96344
#pragma GCC optimize("Ofast,unroll-loops")
// いまの CF だとこれ入れると動かない?
// #pragma GCC target("avx2,popcnt")

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using i128 = __int128;
using u128 = unsigned __int128;
using f128 = __float128;

template <class T>
constexpr T infty = 0;
template <>
constexpr int infty<int> = 1'010'000'000;
template <>
constexpr ll infty<ll> = 2'020'000'000'000'000'000;
template <>
constexpr u32 infty<u32> = infty<int>;
template <>
constexpr u64 infty<u64> = infty<ll>;
template <>
constexpr i128 infty<i128> = i128(infty<ll>) * 2'000'000'000'000'000'000;
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); }
int popcnt_mod_2(int x) { return __builtin_parity(x); }
int popcnt_mod_2(u32 x) { return __builtin_parity(x); }
int popcnt_mod_2(ll x) { return __builtin_parityll(x); }
int popcnt_mod_2(u64 x) { return __builtin_parityll(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>
T floor(T a, T b) {
  return a / b - (a % b && (a ^ b) < 0);
}
template <typename T>
T ceil(T x, T y) {
  return floor(x + y - 1, y);
}
template <typename T>
T bmod(T x, T y) {
  return x - y * floor(x, y);
}
template <typename T>
pair<T, T> divmod(T x, T y) {
  T q = floor(x, y);
  return {q, x - q * y};
}

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

#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) {
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(vc<T> &que) {
  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;
    (check(x) ? ok : ng) = 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;
    (check(x) ? ok : ng) = 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;
}

template <typename T, typename... Vectors>
void concat(vc<T> &first, const Vectors &... others) {
  vc<T> &res = first;
  (res.insert(res.end(), others.begin(), others.end()), ...);
}
#endif
#line 1 "/home/maspy/compro/library/other/io.hpp"
#define FASTIO
#include <unistd.h>

// https://judge.yosupo.jp/submission/21623
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf
uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
  char num[10000][4];
  constexpr Pre() : num() {
    for (int i = 0; i < 10000; i++) {
      int n = i;
      for (int j = 3; j >= 0; j--) {
        num[i][j] = n % 10 | '0';
        n /= 10;
      }
    }
  }
} constexpr pre;

inline void load() {
  memcpy(ibuf, ibuf + pil, pir - pil);
  pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
  pil = 0;
  if (pir < SZ) ibuf[pir++] = '\n';
}

inline void flush() {
  fwrite(obuf, 1, por, stdout);
  por = 0;
}

void rd(char &c) {
  do {
    if (pil + 1 > pir) load();
    c = ibuf[pil++];
  } while (isspace(c));
}

void rd(string &x) {
  x.clear();
  char c;
  do {
    if (pil + 1 > pir) load();
    c = ibuf[pil++];
  } while (isspace(c));
  do {
    x += c;
    if (pil == pir) load();
    c = ibuf[pil++];
  } while (!isspace(c));
}

template <typename T>
void rd_real(T &x) {
  string s;
  rd(s);
  x = stod(s);
}

template <typename T>
void rd_integer(T &x) {
  if (pil + 100 > pir) load();
  char c;
  do
    c = ibuf[pil++];
  while (c < '-');
  bool minus = 0;
  if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
    if (c == '-') { minus = 1, c = ibuf[pil++]; }
  }
  x = 0;
  while ('0' <= c) { x = x * 10 + (c & 15), c = ibuf[pil++]; }
  if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
    if (minus) x = -x;
  }
}

void rd(int &x) { rd_integer(x); }
void rd(ll &x) { rd_integer(x); }
void rd(i128 &x) { rd_integer(x); }
void rd(u32 &x) { rd_integer(x); }
void rd(u64 &x) { rd_integer(x); }
void rd(u128 &x) { rd_integer(x); }
void rd(double &x) { rd_real(x); }
void rd(long double &x) { rd_real(x); }
void rd(f128 &x) { rd_real(x); }

template <class T, class U>
void rd(pair<T, U> &p) {
  return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T>
void rd_tuple(T &t) {
  if constexpr (N < std::tuple_size<T>::value) {
    auto &x = std::get<N>(t);
    rd(x);
    rd_tuple<N + 1>(t);
  }
}
template <class... T>
void rd(tuple<T...> &tpl) {
  rd_tuple(tpl);
}

template <size_t N = 0, typename T>
void rd(array<T, N> &x) {
  for (auto &d: x) rd(d);
}
template <class T>
void rd(vc<T> &x) {
  for (auto &d: x) rd(d);
}

void read() {}
template <class H, class... T>
void read(H &h, T &... t) {
  rd(h), read(t...);
}

void wt(const char c) {
  if (por == SZ) flush();
  obuf[por++] = c;
}
void wt(const string s) {
  for (char c: s) wt(c);
}
void wt(const char *s) {
  size_t len = strlen(s);
  for (size_t i = 0; i < len; i++) wt(s[i]);
}

template <typename T>
void wt_integer(T x) {
  if (por > SZ - 100) flush();
  if (x < 0) { obuf[por++] = '-', x = -x; }
  int outi;
  for (outi = 96; x >= 10000; outi -= 4) {
    memcpy(out + outi, pre.num[x % 10000], 4);
    x /= 10000;
  }
  if (x >= 1000) {
    memcpy(obuf + por, pre.num[x], 4);
    por += 4;
  } else if (x >= 100) {
    memcpy(obuf + por, pre.num[x] + 1, 3);
    por += 3;
  } else if (x >= 10) {
    int q = (x * 103) >> 10;
    obuf[por] = q | '0';
    obuf[por + 1] = (x - q * 10) | '0';
    por += 2;
  } else
    obuf[por++] = x | '0';
  memcpy(obuf + por, out + outi + 4, 96 - outi);
  por += 96 - outi;
}

template <typename T>
void wt_real(T x) {
  ostringstream oss;
  oss << fixed << setprecision(15) << double(x);
  string s = oss.str();
  wt(s);
}

void wt(int x) { wt_integer(x); }
void wt(ll x) { wt_integer(x); }
void wt(i128 x) { wt_integer(x); }
void wt(u32 x) { wt_integer(x); }
void wt(u64 x) { wt_integer(x); }
void wt(u128 x) { wt_integer(x); }
void wt(double x) { wt_real(x); }
void wt(long double x) { wt_real(x); }
void wt(f128 x) { wt_real(x); }

template <class T, class U>
void wt(const pair<T, U> val) {
  wt(val.first);
  wt(' ');
  wt(val.second);
}
template <size_t N = 0, typename T>
void wt_tuple(const T t) {
  if constexpr (N < std::tuple_size<T>::value) {
    if constexpr (N > 0) { wt(' '); }
    const auto x = std::get<N>(t);
    wt(x);
    wt_tuple<N + 1>(t);
  }
}
template <class... T>
void wt(tuple<T...> tpl) {
  wt_tuple(tpl);
}
template <class T, size_t S>
void wt(const array<T, S> val) {
  auto n = val.size();
  for (size_t i = 0; i < n; i++) {
    if (i) wt(' ');
    wt(val[i]);
  }
}
template <class T>
void wt(const vector<T> val) {
  auto n = val.size();
  for (size_t i = 0; i < n; i++) {
    if (i) wt(' ');
    wt(val[i]);
  }
}

void print() { wt('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
  wt(head);
  if (sizeof...(Tail)) wt(' ');
  print(forward<Tail>(tail)...);
}

// gcc expansion. called automaticall after main.
void __attribute__((destructor)) _d() { flush(); }
} // namespace fastio
using fastio::read;
using fastio::print;
using fastio::flush;

#if defined(LOCAL)
#define SHOW(...) SHOW_IMPL(__VA_ARGS__, SHOW6, SHOW5, SHOW4, SHOW3, SHOW2, SHOW1)(__VA_ARGS__)
#define SHOW_IMPL(_1, _2, _3, _4, _5, _6, NAME, ...) NAME
#define SHOW1(x) print(#x, "=", (x)), flush()
#define SHOW2(x, y) print(#x, "=", (x), #y, "=", (y)), flush()
#define SHOW3(x, y, z) print(#x, "=", (x), #y, "=", (y), #z, "=", (z)), flush()
#define SHOW4(x, y, z, w) print(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w)), flush()
#define SHOW5(x, y, z, w, v) print(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", (v)), flush()
#define SHOW6(x, y, z, w, v, u) print(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", (v), #u, "=", (u)), flush()
#else
#define SHOW(...)
#endif

#define INT(...)   \
  int __VA_ARGS__; \
  read(__VA_ARGS__)
#define LL(...)   \
  ll __VA_ARGS__; \
  read(__VA_ARGS__)
#define U32(...)   \
  u32 __VA_ARGS__; \
  read(__VA_ARGS__)
#define U64(...)   \
  u64 __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 3 "main.cpp"

#line 2 "/home/maspy/compro/library/mod/modint_common.hpp"

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>())) {};

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::raw(q));
  }
  return dat[n];
}

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

template <typename mint>
mint fact_inv(int n) {
  static vector<mint> dat = {1, 1};
  if (n < 0) 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 constexpr (dense) return C_dense<mint>(n, k);
  if constexpr (!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 "/home/maspy/compro/library/mod/modint.hpp"

template <int mod>
struct modint {
  static constexpr u32 umod = u32(mod);
  static_assert(umod < u32(1) << 31);
  u32 val;

  static modint raw(u32 v) {
    modint x;
    x.val = v;
    return x;
  }
  constexpr modint() : val(0) {}
  constexpr modint(u32 x) : val(x % umod) {}
  constexpr modint(u64 x) : val(x % umod) {}
  constexpr modint(u128 x) : val(x % umod) {}
  constexpr modint(int x) : val((x %= mod) < 0 ? x + mod : x){};
  constexpr modint(ll x) : val((x %= mod) < 0 ? x + mod : x){};
  constexpr modint(i128 x) : val((x %= mod) < 0 ? x + mod : x){};
  bool operator<(const modint &other) const { return val < other.val; }
  modint &operator+=(const modint &p) {
    if ((val += p.val) >= umod) val -= umod;
    return *this;
  }
  modint &operator-=(const modint &p) {
    if ((val += umod - p.val) >= umod) val -= umod;
    return *this;
  }
  modint &operator*=(const modint &p) {
    val = u64(val) * p.val % umod;
    return *this;
  }
  modint &operator/=(const modint &p) {
    *this *= p.inverse();
    return *this;
  }
  modint operator-() const { return modint::raw(val ? mod - val : u32(0)); }
  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;
  }
  static constexpr int get_mod() { return mod; }
  // (n, r), r は 1 の 2^n 乗根
  static constexpr pair<int, int> ntt_info() {
    if (mod == 120586241) return {20, 74066978};
    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 == 943718401) return {22, 663003469};
    if (mod == 998244353) return {23, 31};
    if (mod == 1004535809) return {21, 582313106};
    if (mod == 1012924417) return {21, 368093570};
    return {-1, -1};
  }
  static constexpr bool can_ntt() { return ntt_info().fi != -1; }
};

#ifdef FASTIO
template <int mod>
void rd(modint<mod> &x) {
  fastio::rd(x.val);
  x.val %= mod;
  // assert(0 <= x.val && x.val < mod);
}
template <int mod>
void wt(modint<mod> x) {
  fastio::wt(x.val);
}
#endif

using modint107 = modint<1000000007>;
using modint998 = modint<998244353>;
#line 2 "/home/maspy/compro/library/alg/monoid_pow.hpp"

// chat gpt
template <typename U, typename Arg1, typename Arg2>
struct has_power_method {
private:
  // ヘルパー関数の実装
  template <typename V, typename A1, typename A2>
  static auto check(int)
      -> decltype(std::declval<V>().power(std::declval<A1>(),
                                          std::declval<A2>()),
                  std::true_type{});
  template <typename, typename, typename>
  static auto check(...) -> std::false_type;

public:
  // メソッドの有無を表す型
  static constexpr bool value = decltype(check<U, Arg1, Arg2>(0))::value;
};

template <typename Monoid>
typename Monoid::X monoid_pow(typename Monoid::X x, ll exp) {
  using X = typename Monoid::X;
  if constexpr (has_power_method<Monoid, X, ll>::value) {
    return Monoid::power(x, exp);
  } else {
    assert(exp >= 0);
    X res = Monoid::unit();
    while (exp) {
      if (exp & 1) res = Monoid::op(res, x);
      x = Monoid::op(x, x);
      exp >>= 1;
    }
    return res;
  }
}
#line 2 "/home/maspy/compro/library/ds/segtree/segtree.hpp"

template <class Monoid>
struct SegTree {
  using MX = Monoid;
  using X = typename MX::value_type;
  using value_type = X;
  vc<X> dat;
  int n, log, size;

  SegTree() {}
  SegTree(int n) { build(n); }
  template <typename F>
  SegTree(int n, F f) {
    build(n, f);
  }
  SegTree(const vc<X>& v) { build(v); }

  void build(int m) {
    build(m, [](int i) -> X { return MX::unit(); });
  }
  void build(const vc<X>& v) {
    build(len(v), [&](int i) -> X { return v[i]; });
  }
  template <typename F>
  void build(int m, F f) {
    n = m, log = 1;
    while ((1 << log) < n) ++log;
    size = 1 << log;
    dat.assign(size << 1, MX::unit());
    FOR(i, n) dat[size + i] = f(i);
    FOR_R(i, 1, size) update(i);
  }

  X get(int i) { return dat[size + i]; }
  vc<X> get_all() { return {dat.begin() + size, dat.begin() + size + n}; }

  void update(int i) { dat[i] = Monoid::op(dat[2 * i], dat[2 * i + 1]); }
  void set(int i, const X& x) {
    assert(i < n);
    dat[i += size] = x;
    while (i >>= 1) update(i);
  }

  void multiply(int i, const X& x) {
    assert(i < n);
    i += size;
    dat[i] = Monoid::op(dat[i], x);
    while (i >>= 1) update(i);
  }

  X prod(int L, int R) {
    assert(0 <= L && L <= R && R <= n);
    X vl = Monoid::unit(), vr = Monoid::unit();
    L += size, R += size;
    while (L < R) {
      if (L & 1) vl = Monoid::op(vl, dat[L++]);
      if (R & 1) vr = Monoid::op(dat[--R], vr);
      L >>= 1, R >>= 1;
    }
    return Monoid::op(vl, vr);
  }

  X prod_all() { return dat[1]; }

  template <class F>
  int max_right(F check, int L) {
    assert(0 <= L && L <= n && check(Monoid::unit()));
    if (L == n) return n;
    L += size;
    X sm = Monoid::unit();
    do {
      while (L % 2 == 0) L >>= 1;
      if (!check(Monoid::op(sm, dat[L]))) {
        while (L < size) {
          L = 2 * L;
          if (check(Monoid::op(sm, dat[L]))) { sm = Monoid::op(sm, dat[L++]); }
        }
        return L - size;
      }
      sm = Monoid::op(sm, dat[L++]);
    } while ((L & -L) != L);
    return n;
  }

  template <class F>
  int min_left(F check, int R) {
    assert(0 <= R && R <= n && check(Monoid::unit()));
    if (R == 0) return 0;
    R += size;
    X sm = Monoid::unit();
    do {
      --R;
      while (R > 1 && (R % 2)) R >>= 1;
      if (!check(Monoid::op(dat[R], sm))) {
        while (R < size) {
          R = 2 * R + 1;
          if (check(Monoid::op(dat[R], sm))) { sm = Monoid::op(dat[R--], sm); }
        }
        return R + 1 - size;
      }
      sm = Monoid::op(dat[R], sm);
    } while ((R & -R) != R);
    return 0;
  }

  // prod_{l<=i<r} A[i xor x]
  X xor_prod(int l, int r, int xor_val) {
    static_assert(Monoid::commute);
    X x = Monoid::unit();
    for (int k = 0; k < log + 1; ++k) {
      if (l >= r) break;
      if (l & 1) { x = Monoid::op(x, dat[(size >> k) + ((l++) ^ xor_val)]); }
      if (r & 1) { x = Monoid::op(x, dat[(size >> k) + ((--r) ^ xor_val)]); }
      l /= 2, r /= 2, xor_val /= 2;
    }
    return x;
  }
};
#line 2 "/home/maspy/compro/library/mod/mod_inv.hpp"

// long でも大丈夫
// (val * x - 1) が mod の倍数になるようにする
// 特に mod=0 なら x=0 が満たす
ll mod_inv(ll val, ll mod) {
  if (mod == 0) return 0;
  mod = abs(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 8 "main.cpp"

using mint = modint998;

vc<int> T;
struct Mono {
  using value_type = array<array<mint, 11>, 11>;
  using X = value_type;
  static X op(X L, X R) {
    array<array<u64, 11>, 11> tmp{};
    FOR(k, 11) FOR(j, k + 1) FOR(i, j + 1) { tmp[i][k] += u64(L[i][j].val) * R[j][k].val; }
    FOR(j, 11) FOR(i, j + 1) L[i][j] = mint(tmp[i][j]);
    return L;
  }
  static constexpr X unit() {
    return {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
  }
  static X from_element(int x) {
    X tmp = unit();
    FOR(i, len(T)) if (T[i] == x) tmp[i][i + 1] = 1;
    return tmp;
  }
  static constexpr bool commute = 0;
};

/*
struct Mono {
  using value_type = vc<int>;
  using X = value_type;
  static X op(X L, X R) {
    concat(L, R);
    return L;
  }
  static X unit() { return {}; }
  static X from_element(int x) { return {x}; }
  static constexpr bool commute = 0;
};
*/

using MAT = typename Mono::value_type;

void drop(vc<pair<int, MAT>>& S) {
  vc<pair<int, MAT>> tmp;
  for (auto& [a, b]: S) {
    if (a > 0) tmp.eb(a, b);
  }
  swap(S, tmp);
}

MAT dfs(vc<pair<int, MAT>> S, int K) {
  if (len(S) == 1) { return monoid_pow<Mono>(S[0].se, S[0].fi); }

  int N = 0;
  for (auto& [a, b]: S) N += a;
  SHOW(N, K);
  if (K * 2 > N) {
    auto [a, b] = S[0];
    S[0].fi--;
    S.eb(1, b);
    reverse(all(S));
    K = N - K;
  }
  SHOW(N, K);
  int n = len(S);
  vc<int> init(n);
  vc<tuple<int, int, int>> event;
  int p = 0;
  FOR(idx, n) {
    const int a = S[idx].fi;
    // [p,p+a)
    vc<int> cut;
    cut.eb(0);
    cut.eb(p % K);
    cut.eb((p + a) % K);
    cut.eb(K);
    UNIQUE(cut);
    FOR(i, len(cut) - 1) {
      int s = cut[i];
      // [p,p+a) のうちで mod K で s
      s = bmod(s - p, K);
      // [0,a) のうちで mod K で s
      // [s,a) のうちで mod K で s
      // [0,b)
      int b = a - s;
      chmax(s, 0);
      int k = ceil<int>(b, K);
      SHOW(s, p, a, k);
      if (cut[i] == 0)
        init[idx] = k;
      else
        event.eb(cut[i], idx, k);
    }
    p += a;
  }
  sort(all(event));
  SegTree<Mono> seg(n, [&](int i) -> MAT { return monoid_pow<Mono>(S[i].se, init[i]); });
  vc<pair<int, MAT>> nxt;
  if (N == 27) SHOW(init);
  p = 0;
  nxt.eb(0, seg.prod_all());
  for (auto& [q, i, n]: event) {
    SHOW(q, i, n);
    nxt.back().fi = q - p;
    p = q;
    seg.set(i, monoid_pow<Mono>(S[i].se, n));
    nxt.eb(0, seg.prod_all());
  }
  nxt.back().fi = K - p;
  drop(nxt);
  for (auto& [a, b]: nxt) SHOW(a, b);
  ll r = K * ceil<ll>(N, K) - N;
  return dfs(nxt, r);
}

void solve() {
  LL(N, M, K, L);
  K = mod_inv(K, L);
  FOR(M) {
    INT(t);
    T.eb(t);
  }

  vc<pair<int, MAT>> dat;
  FOR(N) {
    LL(n, x);
    MAT A = Mono::from_element(x);
    dat.eb(n, A);
  }
  MAT A = dfs(dat, K);
  // print(A[0][M]);
  // print(A);
  SHOW(A);
  print(A[0][M]);
}

signed main() { solve(); }

这程序好像有点Bug,我给组数据试试?

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

4 2 17 27
3 1
10 3
6 1
10 3
1 1

output:

76

result:

ok single line: '76'

Test #2:

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

input:

5 3 1789 15150
555 718 726
72 555
1029 718
5807 726
1002 718
7240 555

output:

390415327

result:

ok single line: '390415327'

Test #3:

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

input:

1 1 1 1000000000
1000
1000000000 1000

output:

1755647

result:

ok single line: '1755647'

Test #4:

score: 0
Accepted
time: 12ms
memory: 7332kb

input:

1999 10 999999999 1000000000
944 901 986 915 979 988 947 999 969 946
198832 985
235662 982
367137 938
219700 949
166086 906
488084 905
891250 984
243743 971
253382 987
181971 935
2382 948
462701 981
4681 925
113363 916
119397 921
337742 982
427128 921
285959 986
197975 978
140753 907
167150 974
4576...

output:

211590728

result:

ok single line: '211590728'

Test #5:

score: 0
Accepted
time: 105ms
memory: 35188kb

input:

2000 10 207560381 499173270
382 246 825 688 810 66 333 717 903 444
242322 825
303194 246
266460 66
133293 444
499376 688
175256 333
260041 717
202138 444
84931 688
353443 825
137750 382
333307 66
450617 810
27484 246
349436 717
45179 444
146073 810
107846 717
416816 246
255378 825
433826 688
273215 ...

output:

686508296

result:

ok single line: '686508296'

Test #6:

score: 0
Accepted
time: 135ms
memory: 37092kb

input:

2000 10 261469558 497769147
990 38 906 66 751 758 913 137 187 724
253600 187
50741 758
58978 724
358384 751
258090 137
423638 990
121415 137
162742 758
93886 724
279287 913
392322 38
495784 758
195957 906
47122 913
87008 751
17599 66
22711 38
58373 724
116467 990
495160 724
471978 758
24585 724
3064...

output:

989869378

result:

ok single line: '989869378'

Test #7:

score: 0
Accepted
time: 142ms
memory: 47584kb

input:

2000 10 321529781 512205698
105 216 706 872 564 639 983 85 153 396
319747 706
46163 639
134011 983
293977 153
176149 983
214154 216
45308 706
270691 396
491463 216
207041 639
118670 983
207549 639
430999 706
294263 872
137031 983
270440 85
480934 153
56566 85
462772 872
53771 639
455400 105
496369 8...

output:

43580469

result:

ok single line: '43580469'

Test #8:

score: 0
Accepted
time: 121ms
memory: 41516kb

input:

2000 10 445061541 492744658
724 778 518 949 399 846 571 290 26 719
95511 399
430323 571
269833 399
378561 778
247054 719
449770 571
452091 719
31296 724
107940 26
330171 724
459597 719
454361 949
71045 724
332444 290
165408 518
123580 719
352964 518
187501 571
206988 778
95308 26
351267 846
22564 77...

output:

616245282

result:

ok single line: '616245282'

Test #9:

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

input:

2000 10 82854895 499384144
533 699 969 632 566 827 967 951 475 208
67174 699
373746 475
43811 827
314087 566
487694 632
150698 475
411781 967
289698 475
202029 967
137762 208
21408 967
185906 632
322311 208
111984 967
219226 533
137525 632
194071 969
415968 951
495074 566
384006 699
75700 533
319248...

output:

325482724

result:

ok single line: '325482724'

Test #10:

score: 0
Accepted
time: 128ms
memory: 40816kb

input:

2000 10 68884267 496908428
911 83 655 38 43 219 401 868 444 362
373884 868
301252 43
71730 83
152590 444
495048 43
220127 868
42667 83
152766 401
295425 911
156010 868
194248 655
258290 362
495166 868
359444 38
228210 83
236963 911
373081 401
219519 38
462869 444
132749 83
126049 362
233585 444
4346...

output:

618545771

result:

ok single line: '618545771'

Test #11:

score: 0
Accepted
time: 108ms
memory: 38344kb

input:

2000 10 296584211 502951247
749 916 549 440 155 770 822 335 591 623
391756 916
403204 335
301242 591
162665 440
377091 623
24972 155
312374 916
171135 623
224221 822
408433 623
157158 822
55740 623
425392 591
37832 916
298703 440
119707 591
101034 749
125274 770
6109 440
78022 916
118181 591
325648 ...

output:

601538508

result:

ok single line: '601538508'

Test #12:

score: 0
Accepted
time: 147ms
memory: 45820kb

input:

2000 10 166200743 502716830
533 628 821 905 330 77 520 46 735 156
96144 46
47146 735
295659 905
171260 156
458468 735
6371 77
76608 330
218288 533
67674 821
140084 520
397185 628
439197 520
466128 77
489650 628
280149 77
235961 821
314891 628
285703 821
456792 533
401436 520
415332 905
335720 735
46...

output:

714220375

result:

ok single line: '714220375'

Test #13:

score: 0
Accepted
time: 142ms
memory: 41208kb

input:

2000 10 494777999 498279924
923 543 789 607 512 597 885 462 759 380
472583 543
70 885
281396 597
31713 885
294039 512
495370 607
338181 380
344775 597
457867 607
362253 543
457963 607
431365 597
489637 923
104753 380
49184 923
452889 543
46665 923
326714 462
332474 923
92685 543
293550 380
223152 51...

output:

867398339

result:

ok single line: '867398339'

Test #14:

score: 0
Accepted
time: 83ms
memory: 30028kb

input:

2000 10 145282979 489563793
128 159 828 90 300 425 977 189 186 533
414271 425
461949 90
173115 300
188953 186
147473 90
361413 300
473121 828
418946 128
449971 828
114925 159
102198 828
420347 300
56815 533
334139 90
384997 977
84207 90
202111 977
318891 90
123614 189
42891 300
48668 128
354240 300
...

output:

642735856

result:

ok single line: '642735856'

Test #15:

score: 0
Accepted
time: 103ms
memory: 33796kb

input:

2000 10 73726788 493104227
599 622 889 670 210 778 374 327 308 768
358274 622
227891 778
375954 768
466366 778
411108 374
347592 599
265078 622
174121 327
355147 374
167867 599
46552 374
10552 778
114210 622
331772 768
302246 599
24244 778
91362 622
130440 889
395599 599
394176 308
81768 374
83741 3...

output:

550082279

result:

ok single line: '550082279'

Test #16:

score: 0
Accepted
time: 170ms
memory: 51692kb

input:

2000 10 152855876 496805251
413 309 740 266 721 715 21 857 206 62
209597 62
330590 857
51271 413
168907 721
473281 21
413081 266
196578 721
219198 21
396781 715
53173 206
200590 266
302416 740
15732 721
414567 740
163152 715
138244 413
158638 62
329207 857
16320 740
246121 21
187905 721
262236 62
90...

output:

937550461

result:

ok single line: '937550461'

Test #17:

score: 0
Accepted
time: 131ms
memory: 43472kb

input:

2000 10 370831065 494204662
382 47 32 870 479 272 956 381 367 794
429604 382
154570 479
61831 382
492147 956
327498 272
427937 381
286339 479
468675 382
197165 479
83760 794
37841 32
283143 870
275120 272
76888 382
438285 381
281443 47
238356 32
353474 794
112098 870
380747 272
161610 479
393113 956...

output:

609619628

result:

ok single line: '609619628'

Test #18:

score: 0
Accepted
time: 74ms
memory: 28472kb

input:

2000 10 200672622 505250813
878 452 69 924 341 370 146 95 189 859
34803 95
36193 859
154299 146
211738 189
69700 859
436922 452
499998 341
338104 69
478735 452
489784 146
180937 189
488456 452
196359 95
126209 924
188052 452
321395 924
189009 859
87452 189
255497 878
43661 341
112027 146
33154 69
44...

output:

56885687

result:

ok single line: '56885687'

Test #19:

score: 0
Accepted
time: 163ms
memory: 49528kb

input:

2000 10 72438867 486841996
394 384 548 742 861 766 155 863 283 525
347582 283
399712 861
451073 394
30203 155
477852 742
146217 861
256320 548
448082 384
104663 155
210939 742
351868 525
253138 548
271447 283
238297 525
464783 394
148139 861
354538 384
260219 155
243223 548
498139 525
291494 863
341...

output:

788937438

result:

ok single line: '788937438'

Test #20:

score: 0
Accepted
time: 148ms
memory: 45560kb

input:

2000 10 12876147 507434473
669 614 751 903 152 518 761 303 63 275
385798 669
260649 275
314982 761
84162 614
324086 669
275099 903
22416 63
216034 669
395106 751
149779 63
474229 303
434728 518
313498 903
9711 152
365631 275
177888 669
496592 152
245728 614
394926 152
10600 63
471425 751
289977 761
...

output:

63922908

result:

ok single line: '63922908'

Test #21:

score: 0
Accepted
time: 166ms
memory: 47600kb

input:

2000 10 240752091 504760936
128 816 447 424 211 177 102 675 680 898
270030 128
30581 177
239215 211
69720 102
285784 447
172262 675
362194 898
308818 177
257890 211
175781 102
352094 816
11391 211
19385 447
375117 177
201000 128
262442 675
237421 102
100994 211
102985 128
85249 177
496945 675
444348...

output:

227952735

result:

ok single line: '227952735'

Test #22:

score: 0
Accepted
time: 180ms
memory: 53916kb

input:

2000 10 237980579 505987937
892 269 84 481 972 522 978 105 450 479
252830 105
189317 450
56029 105
262872 522
279860 978
388378 269
84117 522
131970 105
422569 269
331506 479
96166 450
324575 84
144671 450
140397 978
453063 105
220994 84
150678 450
476768 105
330178 84
296397 105
421757 481
5724 269...

output:

468458072

result:

ok single line: '468458072'

Test #23:

score: 0
Accepted
time: 149ms
memory: 44864kb

input:

2000 10 272341843 508681404
116 160 499 709 151 622 443 51 628 184
41291 628
415609 116
126094 709
36858 116
200281 151
249818 160
126135 622
161783 116
354229 160
378133 709
14269 160
72260 499
217499 628
492068 184
13814 116
206702 499
141318 628
489670 116
347538 184
337073 499
257293 622
234135 ...

output:

5538813

result:

ok single line: '5538813'

Test #24:

score: 0
Accepted
time: 125ms
memory: 39224kb

input:

2000 10 356002797 504473516
719 731 800 845 438 24 89 893 91 616
209787 800
11719 89
184449 438
63108 91
331474 719
368355 438
286223 893
100984 91
308890 719
364976 91
244872 845
303525 731
205243 91
147458 800
216532 89
497673 800
280025 719
456560 91
305453 89
254073 24
48745 893
460814 438
27832...

output:

986718855

result:

ok single line: '986718855'

Test #25:

score: 0
Accepted
time: 141ms
memory: 44624kb

input:

2000 10 127175740 494689853
275 190 710 754 848 8 273 837 501 733
440135 8
333895 501
210229 190
88530 273
316662 190
42142 837
163058 8
155823 275
206862 273
23687 837
217900 733
269239 501
463533 710
489832 501
296607 8
364225 501
361620 190
69562 754
220522 273
8424 754
447614 848
292734 501
3145...

output:

297118416

result:

ok single line: '297118416'

Test #26:

score: 0
Accepted
time: 153ms
memory: 45092kb

input:

2000 10 183513063 506311438
833 936 339 149 842 216 182 627 896 257
275174 216
238462 627
100861 896
135959 182
230471 842
273524 149
403111 936
365497 896
331581 149
154269 257
225488 936
458484 339
13236 627
261000 216
6749 339
46847 833
341899 149
46436 257
462934 339
149769 216
330206 257
133342...

output:

23998350

result:

ok single line: '23998350'

Extra Test:

score: 0
Extra Test Passed