QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#251658 | #7564. Game | ucup-team133 | AC ✓ | 3668ms | 76508kb | C++17 | 28.6kb | 2023-11-14 22:43:14 | 2023-11-14 22:43:16 |
Judging History
answer
// -fsanitize=undefined,
//#define _GLIBCXX_DEBUG
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <random>
#include <stdio.h>
#include <fstream>
#include <functional>
#include <cassert>
#include <unordered_map>
#include <bitset>
//#include <atcoder/all>
#include <utility>
namespace atcoder {
namespace internal {
// @param m `1 <= m`
// @return x mod m
constexpr long long safe_mod(long long x, long long m) {
x %= m;
if (x < 0) x += m;
return x;
}
// Fast moduler by barrett reduction
// Reference: https://en.wikipedia.org/wiki/Barrett_reduction
// NOTE: reconsider after Ice Lake
struct barrett {
unsigned int _m;
unsigned long long im;
// @param m `1 <= m`
barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}
// @return m
unsigned int umod() const { return _m; }
// @param a `0 <= a < m`
// @param b `0 <= b < m`
// @return `a * b % m`
unsigned int mul(unsigned int a, unsigned int b) const {
// [1] m = 1
// a = b = im = 0, so okay
// [2] m >= 2
// im = ceil(2^64 / m)
// -> im * m = 2^64 + r (0 <= r < m)
// let z = a*b = c*m + d (0 <= c, d < m)
// a*b * im = (c*m + d) * im = c*(im*m) + d*im = c*2^64 + c*r + d*im
// c*r + d*im < m * m + m * im < m * m + 2^64 + m <= 2^64 + m * (m + 1) < 2^64 * 2
// ((ab * im) >> 64) == c or c + 1
unsigned long long z = a;
z *= b;
#ifdef _MSC_VER
unsigned long long x;
_umul128(z, im, &x);
#else
unsigned long long x =
(unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
unsigned int v = (unsigned int)(z - x * _m);
if (_m <= v) v += _m;
return v;
}
};
// @param n `0 <= n`
// @param m `1 <= m`
// @return `(x ** n) % m`
constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
if (m == 1) return 0;
unsigned int _m = (unsigned int)(m);
unsigned long long r = 1;
unsigned long long y = safe_mod(x, m);
while (n) {
if (n & 1) r = (r * y) % _m;
y = (y * y) % _m;
n >>= 1;
}
return r;
}
// Reference:
// M. Forisek and J. Jancina,
// Fast Primality Testing for Integers That Fit into a Machine Word
// @param n `0 <= n`
constexpr bool is_prime_constexpr(int n) {
if (n <= 1) return false;
if (n == 2 || n == 7 || n == 61) return true;
if (n % 2 == 0) return false;
long long d = n - 1;
while (d % 2 == 0) d /= 2;
for (long long a : {2, 7, 61}) {
long long t = d;
long long y = pow_mod_constexpr(a, t, n);
while (t != n - 1 && y != 1 && y != n - 1) {
y = y * y % n;
t <<= 1;
}
if (y != n - 1 && t % 2 == 0) {
return false;
}
}
return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);
// @param b `1 <= b`
// @return pair(g, x) s.t. g = gcd(a, b), xa = g (mod b), 0 <= x < b/g
constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
a = safe_mod(a, b);
if (a == 0) return {b, 0};
// Contracts:
// [1] s - m0 * a = 0 (mod b)
// [2] t - m1 * a = 0 (mod b)
// [3] s * |m1| + t * |m0| <= b
long long s = b, t = a;
long long m0 = 0, m1 = 1;
while (t) {
long long u = s / t;
s -= t * u;
m0 -= m1 * u; // |m1 * u| <= |m1| * s <= b
// [3]:
// (s - t * u) * |m1| + t * |m0 - m1 * u|
// <= s * |m1| - t * u * |m1| + t * (|m0| + |m1| * u)
// = s * |m1| + t * |m0| <= b
auto tmp = s;
s = t;
t = tmp;
tmp = m0;
m0 = m1;
m1 = tmp;
}
// by [3]: |m0| <= b/g
// by g != b: |m0| < b/g
if (m0 < 0) m0 += b / s;
return {s, m0};
}
// Compile time primitive root
// @param m must be prime
// @return primitive root (and minimum in now)
constexpr int primitive_root_constexpr(int m) {
if (m == 2) return 1;
if (m == 167772161) return 3;
if (m == 469762049) return 3;
if (m == 754974721) return 11;
if (m == 998244353) return 3;
int divs[20] = {};
divs[0] = 2;
int cnt = 1;
int x = (m - 1) / 2;
while (x % 2 == 0) x /= 2;
for (int i = 3; (long long)(i)*i <= x; i += 2) {
if (x % i == 0) {
divs[cnt++] = i;
while (x % i == 0) {
x /= i;
}
}
}
if (x > 1) {
divs[cnt++] = x;
}
for (int g = 2;; g++) {
bool ok = true;
for (int i = 0; i < cnt; i++) {
if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
ok = false;
break;
}
}
if (ok) return g;
}
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);
} // namespace internal
} // namespace atcoder
#include <cassert>
#include <numeric>
#include <type_traits>
namespace atcoder {
namespace internal {
#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
typename std::conditional<std::is_same<T, __int128_t>::value ||
std::is_same<T, __int128>::value,
std::true_type,
std::false_type>::type;
template <class T>
using is_unsigned_int128 =
typename std::conditional<std::is_same<T, __uint128_t>::value ||
std::is_same<T, unsigned __int128>::value,
std::true_type,
std::false_type>::type;
template <class T>
using make_unsigned_int128 =
typename std::conditional<std::is_same<T, __int128_t>::value,
__uint128_t,
unsigned __int128>;
template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
is_signed_int128<T>::value ||
is_unsigned_int128<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
std::is_signed<T>::value) ||
is_signed_int128<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using is_unsigned_int =
typename std::conditional<(is_integral<T>::value &&
std::is_unsigned<T>::value) ||
is_unsigned_int128<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using to_unsigned = typename std::conditional<
is_signed_int128<T>::value,
make_unsigned_int128<T>,
typename std::conditional<std::is_signed<T>::value,
std::make_unsigned<T>,
std::common_type<T>>::type>::type;
#else
template <class T> using is_integral = typename std::is_integral<T>;
template <class T>
using is_signed_int =
typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using is_unsigned_int =
typename std::conditional<is_integral<T>::value &&
std::is_unsigned<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
std::make_unsigned<T>,
std::common_type<T>>::type;
#endif
template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;
template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;
template <class T> using to_unsigned_t = typename to_unsigned<T>::type;
} // namespace internal
} // namespace atcoder
#include <cassert>
#include <numeric>
#include <type_traits>
#ifdef _MSC_VER
#include <intrin.h>
#endif
namespace atcoder {
namespace internal {
struct modint_base {};
struct static_modint_base : modint_base {};
template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;
} // namespace internal
template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
using mint = static_modint;
public:
static constexpr int mod() { return m; }
static mint raw(int v) {
mint x;
x._v = v;
return x;
}
static_modint() : _v(0) {}
template <class T, internal::is_signed_int_t<T>* = nullptr>
static_modint(T v) {
long long x = (long long)(v % (long long)(umod()));
if (x < 0) x += umod();
_v = (unsigned int)(x);
}
template <class T, internal::is_unsigned_int_t<T>* = nullptr>
static_modint(T v) {
_v = (unsigned int)(v % umod());
}
static_modint(bool v) { _v = ((unsigned int)(v) % umod()); }
unsigned int val() const { return _v; }
mint& operator++() {
_v++;
if (_v == umod()) _v = 0;
return *this;
}
mint& operator--() {
if (_v == 0) _v = umod();
_v--;
return *this;
}
mint operator++(int) {
mint result = *this;
++*this;
return result;
}
mint operator--(int) {
mint result = *this;
--*this;
return result;
}
mint& operator+=(const mint& rhs) {
_v += rhs._v;
if (_v >= umod()) _v -= umod();
return *this;
}
mint& operator-=(const mint& rhs) {
_v -= rhs._v;
if (_v >= umod()) _v += umod();
return *this;
}
mint& operator*=(const mint& rhs) {
unsigned long long z = _v;
z *= rhs._v;
_v = (unsigned int)(z % umod());
return *this;
}
mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }
mint operator+() const { return *this; }
mint operator-() const { return mint() - *this; }
mint pow(long long n) const {
assert(0 <= n);
mint x = *this, r = 1;
while (n) {
if (n & 1) r *= x;
x *= x;
n >>= 1;
}
return r;
}
mint inv() const {
if (prime) {
assert(_v);
return pow(umod() - 2);
} else {
auto eg = internal::inv_gcd(_v, m);
assert(eg.first == 1);
return eg.second;
}
}
friend mint operator+(const mint& lhs, const mint& rhs) {
return mint(lhs) += rhs;
}
friend mint operator-(const mint& lhs, const mint& rhs) {
return mint(lhs) -= rhs;
}
friend mint operator*(const mint& lhs, const mint& rhs) {
return mint(lhs) *= rhs;
}
friend mint operator/(const mint& lhs, const mint& rhs) {
return mint(lhs) /= rhs;
}
friend bool operator==(const mint& lhs, const mint& rhs) {
return lhs._v == rhs._v;
}
friend bool operator!=(const mint& lhs, const mint& rhs) {
return lhs._v != rhs._v;
}
private:
unsigned int _v;
static constexpr unsigned int umod() { return m; }
static constexpr bool prime = internal::is_prime<m>;
};
template <int id> struct dynamic_modint : internal::modint_base {
using mint = dynamic_modint;
public:
static int mod() { return (int)(bt.umod()); }
static void set_mod(int m) {
assert(1 <= m);
bt = internal::barrett(m);
}
static mint raw(int v) {
mint x;
x._v = v;
return x;
}
dynamic_modint() : _v(0) {}
template <class T, internal::is_signed_int_t<T>* = nullptr>
dynamic_modint(T v) {
long long x = (long long)(v % (long long)(mod()));
if (x < 0) x += mod();
_v = (unsigned int)(x);
}
template <class T, internal::is_unsigned_int_t<T>* = nullptr>
dynamic_modint(T v) {
_v = (unsigned int)(v % mod());
}
dynamic_modint(bool v) { _v = ((unsigned int)(v) % mod()); }
unsigned int val() const { return _v; }
mint& operator++() {
_v++;
if (_v == umod()) _v = 0;
return *this;
}
mint& operator--() {
if (_v == 0) _v = umod();
_v--;
return *this;
}
mint operator++(int) {
mint result = *this;
++*this;
return result;
}
mint operator--(int) {
mint result = *this;
--*this;
return result;
}
mint& operator+=(const mint& rhs) {
_v += rhs._v;
if (_v >= umod()) _v -= umod();
return *this;
}
mint& operator-=(const mint& rhs) {
_v += mod() - rhs._v;
if (_v >= umod()) _v -= umod();
return *this;
}
mint& operator*=(const mint& rhs) {
_v = bt.mul(_v, rhs._v);
return *this;
}
mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }
mint operator+() const { return *this; }
mint operator-() const { return mint() - *this; }
mint pow(long long n) const {
assert(0 <= n);
mint x = *this, r = 1;
while (n) {
if (n & 1) r *= x;
x *= x;
n >>= 1;
}
return r;
}
mint inv() const {
auto eg = internal::inv_gcd(_v, mod());
assert(eg.first == 1);
return eg.second;
}
friend mint operator+(const mint& lhs, const mint& rhs) {
return mint(lhs) += rhs;
}
friend mint operator-(const mint& lhs, const mint& rhs) {
return mint(lhs) -= rhs;
}
friend mint operator*(const mint& lhs, const mint& rhs) {
return mint(lhs) *= rhs;
}
friend mint operator/(const mint& lhs, const mint& rhs) {
return mint(lhs) /= rhs;
}
friend bool operator==(const mint& lhs, const mint& rhs) {
return lhs._v == rhs._v;
}
friend bool operator!=(const mint& lhs, const mint& rhs) {
return lhs._v != rhs._v;
}
private:
unsigned int _v;
static internal::barrett bt;
static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt = 998244353;
using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;
namespace internal {
template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;
template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;
template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};
template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;
} // namespace internal
} // namespace atcoder
#include <algorithm>
#include <array>
#ifdef _MSC_VER
#include <intrin.h>
#endif
namespace atcoder {
namespace internal {
// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
int x = 0;
while ((1U << x) < (unsigned int)(n)) x++;
return x;
}
// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
unsigned long index;
_BitScanForward(&index, n);
return index;
#else
return __builtin_ctz(n);
#endif
}
} // namespace internal
} // namespace atcoder
#include <cassert>
#include <type_traits>
#include <vector>
namespace atcoder {
namespace internal {
template <class mint, internal::is_static_modint_t<mint>* = nullptr>
void butterfly(std::vector<mint>& a) {
static constexpr int g = internal::primitive_root<mint::mod()>;
int n = int(a.size());
int h = internal::ceil_pow2(n);
static bool first = true;
static mint sum_e[30]; // sum_e[i] = ies[0] * ... * ies[i - 1] * es[i]
if (first) {
first = false;
mint es[30], ies[30]; // es[i]^(2^(2+i)) == 1
int cnt2 = bsf(mint::mod() - 1);
mint e = mint(g).pow((mint::mod() - 1) >> cnt2), ie = e.inv();
for (int i = cnt2; i >= 2; i--) {
// e^(2^i) == 1
es[i - 2] = e;
ies[i - 2] = ie;
e *= e;
ie *= ie;
}
mint now = 1;
for (int i = 0; i < cnt2 - 2; i++) {
sum_e[i] = es[i] * now;
now *= ies[i];
}
}
for (int ph = 1; ph <= h; ph++) {
int w = 1 << (ph - 1), p = 1 << (h - ph);
mint now = 1;
for (int s = 0; s < w; s++) {
int offset = s << (h - ph + 1);
for (int i = 0; i < p; i++) {
auto l = a[i + offset];
auto r = a[i + offset + p] * now;
a[i + offset] = l + r;
a[i + offset + p] = l - r;
}
now *= sum_e[bsf(~(unsigned int)(s))];
}
}
}
template <class mint, internal::is_static_modint_t<mint>* = nullptr>
void butterfly_inv(std::vector<mint>& a) {
static constexpr int g = internal::primitive_root<mint::mod()>;
int n = int(a.size());
int h = internal::ceil_pow2(n);
static bool first = true;
static mint sum_ie[30]; // sum_ie[i] = es[0] * ... * es[i - 1] * ies[i]
if (first) {
first = false;
mint es[30], ies[30]; // es[i]^(2^(2+i)) == 1
int cnt2 = bsf(mint::mod() - 1);
mint e = mint(g).pow((mint::mod() - 1) >> cnt2), ie = e.inv();
for (int i = cnt2; i >= 2; i--) {
// e^(2^i) == 1
es[i - 2] = e;
ies[i - 2] = ie;
e *= e;
ie *= ie;
}
mint now = 1;
for (int i = 0; i < cnt2 - 2; i++) {
sum_ie[i] = ies[i] * now;
now *= es[i];
}
}
for (int ph = h; ph >= 1; ph--) {
int w = 1 << (ph - 1), p = 1 << (h - ph);
mint inow = 1;
for (int s = 0; s < w; s++) {
int offset = s << (h - ph + 1);
for (int i = 0; i < p; i++) {
auto l = a[i + offset];
auto r = a[i + offset + p];
a[i + offset] = l + r;
a[i + offset + p] =
(unsigned long long)(mint::mod() + l.val() - r.val()) *
inow.val();
}
inow *= sum_ie[bsf(~(unsigned int)(s))];
}
}
}
} // namespace internal
template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution(std::vector<mint> a, std::vector<mint> b) {
int n = int(a.size()), m = int(b.size());
if (!n || !m) return {};
if (std::min(n, m) <= 60) {
if (n < m) {
std::swap(n, m);
std::swap(a, b);
}
std::vector<mint> ans(n + m - 1);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
ans[i + j] += a[i] * b[j];
}
}
return ans;
}
int z = 1 << internal::ceil_pow2(n + m - 1);
a.resize(z);
internal::butterfly(a);
b.resize(z);
internal::butterfly(b);
for (int i = 0; i < z; i++) {
a[i] *= b[i];
}
internal::butterfly_inv(a);
a.resize(n + m - 1);
mint iz = mint(z).inv();
for (int i = 0; i < n + m - 1; i++) a[i] *= iz;
return a;
}
template <unsigned int mod = 998244353,
class T,
std::enable_if_t<internal::is_integral<T>::value>* = nullptr>
std::vector<T> convolution(const std::vector<T>& a, const std::vector<T>& b) {
int n = int(a.size()), m = int(b.size());
if (!n || !m) return {};
using mint = static_modint<mod>;
std::vector<mint> a2(n), b2(m);
for (int i = 0; i < n; i++) {
a2[i] = mint(a[i]);
}
for (int i = 0; i < m; i++) {
b2[i] = mint(b[i]);
}
auto c2 = convolution(move(a2), move(b2));
std::vector<T> c(n + m - 1);
for (int i = 0; i < n + m - 1; i++) {
c[i] = c2[i].val();
}
return c;
}
std::vector<long long> convolution_ll(const std::vector<long long>& a,
const std::vector<long long>& b) {
int n = int(a.size()), m = int(b.size());
if (!n || !m) return {};
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 constexpr unsigned long long i1 =
internal::inv_gcd(MOD2 * MOD3, MOD1).second;
static constexpr unsigned long long i2 =
internal::inv_gcd(MOD1 * MOD3, MOD2).second;
static constexpr unsigned long long i3 =
internal::inv_gcd(MOD1 * MOD2, MOD3).second;
auto c1 = convolution<MOD1>(a, b);
auto c2 = convolution<MOD2>(a, b);
auto c3 = convolution<MOD3>(a, b);
std::vector<long long> c(n + m - 1);
for (int i = 0; i < n + m - 1; i++) {
unsigned long long x = 0;
x += (c1[i] * i1) % MOD1 * M2M3;
x += (c2[i] * i2) % MOD2 * M1M3;
x += (c3[i] * i3) % MOD3 * M1M2;
// B = 2^63, -B <= x, r(real value) < B
// (x, x - M, x - 2M, or x - 3M) = r (mod 2B)
// r = c1[i] (mod MOD1)
// focus on MOD1
// r = x, x - M', x - 2M', x - 3M' (M' = M % 2^64) (mod 2B)
// r = x,
// x - M' + (0 or 2B),
// x - 2M' + (0, 2B or 4B),
// x - 3M' + (0, 2B, 4B or 6B) (without mod!)
// (r - x) = 0, (0)
// - M' + (0 or 2B), (1)
// -2M' + (0 or 2B or 4B), (2)
// -3M' + (0 or 2B or 4B or 6B) (3) (mod MOD1)
// we checked that
// ((1) mod MOD1) mod 5 = 2
// ((2) mod MOD1) mod 5 = 3
// ((3) mod MOD1) mod 5 = 4
long long diff =
c1[i] - internal::safe_mod((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;
}
} // namespace atcoder
using namespace std;
using namespace atcoder;
#define rep(i,n) for (int i=0;i<n;i+=1)
#define rrep(i,n) for (int i=n-1;i>-1;i--)
#define pb push_back
#define all(x) (x).begin(), (x).end()
template<class T>
using vec = vector<T>;
template<class T>
using vvec = vec<vec<T>>;
template<class T>
using vvvec = vec<vvec<T>>;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
template<class T>
bool chmin(T &a, T b){
if (a>b){
a = b;
return true;
}
return false;
}
template<class T>
bool chmax(T &a, T b){
if (a<b){
a = b;
return true;
}
return false;
}
template<class T>
T sum(vec<T> x){
T res=0;
for (auto e:x){
res += e;
}
return res;
}
template<class T>
void printv(vec<T> x){
for (auto e:x){
cout<<e<<" ";
}
cout<<endl;
}
template<class T>
ostream& operator<<(ostream& os, const vec<T>& A){
os << "[";
rep(i,A.size()){
os << A[i];
if (i!=A.size()-1){
os << ", ";
}
}
os << "]" ;
return os;
}
template<class T,class U>
ostream& operator<<(ostream& os, const pair<T,U>& A){
os << "(" << A.first <<", " << A.second << ")";
return os;
}
template<class T>
ostream& operator<<(ostream& os, const set<T>& S){
os << "set{";
for (auto a:S){
os << a;
auto it = S.find(a);
it++;
if (it!=S.end()){
os << ", ";
}
}
os << "}";
return os;
}
using mint = modint998244353;
ostream& operator<<(ostream& os, const mint& a){
os << a.val();
return os;
}
mint g1[200100],g2[200100],inverse[200100];
void init_comb(){
g1[0] = 1; g1[1] = 1; g2[0] = 1; g2[1] = 1; inverse[1] = 1;
for (int n=2;n<=200000;n++){
g1[n] = g1[n-1] * n;
inverse[n] = -inverse[998244353%n] * (998244353/n);
g2[n] = g2[n-1] * inverse[n];
}
}
vec<mint> taylor_shift(vec<mint> f,mint a){
int n = f.size();
vec<mint> g(n);
rep(i,n) g[i] = f[i] * g1[i];
reverse(all(g));
vec<mint> e(n);
rep(i,n) e[i] = g2[i] * a.pow(i);
vec<mint> res = convolution(g,e);
res.resize(n);
assert (int(res.size()) == n);
vec<mint> ans(n);
rep(i,n) ans[i] = res[n-1-i] * g2[i];
return ans;
}
vec<mint> poly_inv(vec<mint> f,int D){
int k = f.size();
int L = 1, n = 0;
while (L < D){
L <<= 1;
n += 1;
}
f.resize(L);
cout << f << endl;
vec<mint> res = {f[0].inv()};
for (int i=1;i<=n;i++){
auto h = convolution(res,{f.begin(),f.begin()+min((1<<i),k)});
h.resize(1<<i);
rep(j,1<<i) h[j] *= -1;
h[0] += 2;
res = convolution(res,h);
res.resize(1<<i);
}
res.resize(D);
cout << res << endl;
return res;
}
int tmp[27][27][27][27][27];
const int M = 5;
void solve(){
int N;
cin>>N;
vec<vec<int>> L(N,vec<int>(5,-1)),R(N,vec<int>(5,-1));
for (int i=0;i<N;i++){
string S,T;
cin>>S>>T;
for (int j=0;j<M;j++){
if (T[j] == '>'){
L[i][j] = S[j] - 'A' + 1;
R[i][j] = 26;
}
else if (T[j] == '='){
L[i][j] = S[j] - 'A';
R[i][j] = S[j] - 'A' + 1;
}
else{
L[i][j] = 0;
R[i][j] = S[j] - 'A';
}
}
//cout << L[i] << " " << R[i] << endl;
}
vec<mint> cnt(N+1,0);
for (int S=0;S<(1<<M);S++){
rep(a,26) rep(b,26) rep(c,26) rep(d,26) rep(e,26) tmp[a][b][c][d][e] = 0;
for (int i=0;i<N;i++){
for (int T=0;T<(1<<M);T++){
vec<int> add_point(5,0);
int sgn = 1;
for (int k=0;k<M;k++){
if ((S>>k) & 1 && L[i][k] == R[i][k]) sgn = 0;
if (((T>>k) & 1) == 0){
add_point[k] = L[i][k];
}
else{
sgn *= -1;
add_point[k] = R[i][k] - ((S>>k) & 1);
}
}
//cout << i << " " << T << endl;
//cout << add_point << endl;
if (sgn!=0){
tmp[add_point[0]][add_point[1]][add_point[2]][add_point[3]][add_point[4]] += sgn;
}
}
}
rep(a,25) rep(b,26) rep(c,26) rep(d,26) rep(e,26) tmp[a+1][b][c][d][e] += tmp[a][b][c][d][e];
rep(a,26) rep(b,25) rep(c,26) rep(d,26) rep(e,26) tmp[a][b+1][c][d][e] += tmp[a][b][c][d][e];
rep(a,26) rep(b,26) rep(c,25) rep(d,26) rep(e,26) tmp[a][b][c+1][d][e] += tmp[a][b][c][d][e];
rep(a,26) rep(b,26) rep(c,26) rep(d,25) rep(e,26) tmp[a][b][c][d+1][e] += tmp[a][b][c][d][e];
rep(a,26) rep(b,26) rep(c,26) rep(d,26) rep(e,25) tmp[a][b][c][d][e+1] += tmp[a][b][c][d][e];
int sgn = 1;
for (int k=0;k<M;k++){
if ((S>>k) & 1) sgn *= -1;
}
rep(a,26) rep(b,26) rep(c,26) rep(d,26) rep(e,26) cnt[tmp[a][b][c][d][e]] += sgn;
}
auto cnt_det_set = taylor_shift(cnt,1);
assert (int(cnt_det_set.size()) == N+1);
rep(i,N+1) cnt_det_set[i] = g1[N] * g2[i] * g2[N-i] - cnt_det_set[i];
cnt_det_set[0] = 0;
rep(i,N+1){
cnt_det_set[i] *= g1[i] * g1[N-i];
}
//cout << cnt_det_set << endl;
for (int i=N;0<i;i--){
cnt_det_set[i] -= cnt_det_set[i-1];
cnt_det_set[i] *= g2[N-i];
}
for (int i=1;i<=N;i++){
cout << cnt_det_set[i] << " ";
}
cout << "\n";
return ;
}
int main(){
ios::sync_with_stdio(false);
std::cin.tie(nullptr);
init_comb();
int T = 1;
while (T--){
solve();
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1614ms
memory: 61416kb
input:
2 FAKER >>>>> CHOVY =====
output:
0 2
result:
ok 2 number(s): "0 2"
Test #2:
score: 0
Accepted
time: 1616ms
memory: 61168kb
input:
3 BVHUQ ><>>< YJCEQ <<><< SXXWZ >>==>
output:
1 4 0
result:
ok 3 number(s): "1 4 0"
Test #3:
score: 0
Accepted
time: 1662ms
memory: 60140kb
input:
8 IFSXA >><<= ZAKDA <>=>= UZVAA <<<>= MTACA <>>>= RJKVA <><<= IOXOA >=<<= MRMHA ><<<= BYFWA ==<>=
output:
0 16 108 396 816 720 0 0
result:
ok 8 numbers
Test #4:
score: 0
Accepted
time: 1503ms
memory: 59268kb
input:
8 BRKPR ><=<> VUCTO <<=<= PTCDB <<=>> PHMGV <><>< FGWHD >><>> SUSFH <<<<> IOLDD <<<<> WJPXX <><<<
output:
0 14 120 444 744 360 0 0
result:
ok 8 numbers
Test #5:
score: 0
Accepted
time: 1620ms
memory: 59820kb
input:
10 UAVZE =>=<= QVGJB >==>> ZLHUS >>>=> PGZOO ==<>< LAKYL =<=<= IMQAQ <>>== OBWGV >>=<> KQSOR <<>>= KGFVD >=<== RFDGJ <>><>
output:
2 66 48 0 0 0 0 0 0 0
result:
ok 10 numbers
Test #6:
score: 0
Accepted
time: 1665ms
memory: 59300kb
input:
10 GOMVB >>>>< DSPSI =><== UKTNW <<>=< SKNLH >=<>< TNYRS =<<>< QZHXW <==>> NLWVU ><=>= WHBAI ><>>= QXDIC <=<>> JBUFE =>==<
output:
0 86 32 0 0 0 0 0 0 0
result:
ok 10 numbers
Test #7:
score: 0
Accepted
time: 1646ms
memory: 60356kb
input:
10 SBDSY >>>=> NSYAP <><>= PIFGA >=>=> URDJY <>>>< EDLLY =><<> ZLWTD >>>>= OTTLU <><=< HYKKZ ===<< VRBUB =<><> AXKEY <==<>
output:
2 60 90 42 0 0 0 0 0 0
result:
ok 10 numbers
Test #8:
score: 0
Accepted
time: 1316ms
memory: 59648kb
input:
10 CPIAM ><>>> FZBGT ><>>> EUFKN ><>=> OWUOO <<<<> RJOOA <>><> VOMTV <<><= FZAYC ><><> GOQML ><><> WZGOV <<><= AAAAA <<<<<
output:
1 9 72 504 3024 15120 60480 181440 362880 362880
result:
ok 10 numbers
Test #9:
score: 0
Accepted
time: 1386ms
memory: 59740kb
input:
10 MYAFR <<>=< UUOJK <<><> AWYJM ><=<> FOSPK ><><> TUUIA <<><> OJAMS <>><< BUEGG ><>>> PTDUK <<><> SBLYM <>><> SFAAX >>>==
output:
0 14 128 816 4344 19320 65520 146160 161280 0
result:
ok 10 numbers
Test #10:
score: 0
Accepted
time: 1303ms
memory: 61084kb
input:
10 QJQVM <>>>< NYNHE ><>>< WSBQB <<>>> ONXCP <<<>< CKICH >>>>< CQHZL >>><< SPKWY <<<<< FAXVS >><<< RVBOC <<><> TRPLG =>>==
output:
0 28 250 1146 2856 3000 0 0 0 0
result:
ok 10 numbers
Test #11:
score: 0
Accepted
time: 1329ms
memory: 60924kb
input:
10 PDOHN <>>>< YIBBD <>>>< VKHGC <><>> KLJOB ><>>> DIUHJ >>=>< AGDCK ><>>> FFXBK >><>< CHIEL ><>>> HGPXS >>><< GFHRX =>>=<
output:
0 38 230 822 2040 3480 2880 0 0 0
result:
ok 10 numbers
Test #12:
score: 0
Accepted
time: 1375ms
memory: 61168kb
input:
10 BWSGL ><<>> XEXGK <><>> OUHKP <>>=< ZWXCT <><>< VWAOX ><><< KXAHA ><>>> VVFUL ><<<> RHBTD >>><> FHBMB >>=<> JKVSX >==>>
output:
0 32 242 930 2424 5160 5760 0 0 0
result:
ok 10 numbers
Test #13:
score: 0
Accepted
time: 1416ms
memory: 60324kb
input:
10 TFXCY >><<< ALEDI ><>>> YBXWE <><<> YVCHH <<>>< JCYDR ><=>< GNURG ><<<< QFLEM <>>>> JUUHR ><><< LMDZE ><><< TEDEE >>=><
output:
0 46 268 564 144 0 0 0 0 0
result:
ok 10 numbers
Test #14:
score: 0
Accepted
time: 3615ms
memory: 76376kb
input:
100000 BNLGH >>=== QXYTZ >>=>> NRBRX <==== HSKHN <<>>> WPOWG >===> UXFEU =><>> GROWO =><>> VPKSO <><>< WKUQA ===>> KGKHU >=>>> YSIHF >=>>< TOSXN <=>=< HTCKZ =>=>= LIDLA >==>= MNVDK <<<=> WHGMQ ><>>= BRCSN ><<>> YLOEF <<==> IBVUP <><== JHWHE <==>> CBSKF >==>= OLGHJ <>><< OUDND =>==< AMFMU =<=== SDUHG...
output:
12144 412636794 259958531 471914400 521830768 776198196 987954473 677670949 929976028 435141791 915818255 77808332 373696275 860004456 815590598 827302790 334750217 297638785 684154009 734333884 468372005 941077614 669579770 347535008 712117434 881704206 973579427 385468207 664289497 158009373 53637...
result:
ok 100000 numbers
Test #15:
score: 0
Accepted
time: 3617ms
memory: 76364kb
input:
100000 YZHMP ><<== WTMOD <>><< RPZJR >=>=< AAJNC ===>= DIHKN =><>< ANVCM <<><= GLDOE <><=> KSNER <>>== WRKUF =<<>< ESGBH =><=< QTAKH <>=>< JGOSQ ><<<= MYSQR =>>== KLRPC =<=>< QRMKD ===== FCBZE >>>=< BNXDB =><=> NNRQD >==== BPVWI ==<=< KXEYZ ===>< IJMLR ==<>< ZGHZX =<=>< NDLJA <=<<< NOVNI ><<<< JKSRM...
output:
12223 400459039 28986202 438885749 273376351 163951784 446281085 40534769 335228183 96236785 880355311 987490628 488442137 827131227 536678086 420675015 209408414 489894579 26613846 266498745 429205709 284226414 110233883 328154083 561800066 269995982 113946391 76900398 905441256 821243833 20626991 ...
result:
ok 100000 numbers
Test #16:
score: 0
Accepted
time: 3524ms
memory: 76428kb
input:
100000 UNCSX <<==< FOYMG =<==< WQXDL <=<>= RKJSP <=>>= LAXXT ><<== IEMZF ==><= DFSET >=><= CWRSU <<>== XBCYM ><=>< YFAWT >><=< HTRNJ <<<>> ZWKMT ===>= QDLYL <<=<< JOFQE ==<>> SWETU <<><> MYVMS =<>=< DGRNR =<>>< CNXBA <<<>= WDWYZ =<>>> KPNNU >=>=< QTGOB ==<>< JCHUK ><=== MLTEW =<>=> DTMMV =<=>= BSPZQ...
output:
12256 398686308 110275411 25618548 98398475 75789291 450067286 554959802 735917475 608870282 245681817 893103261 540261582 229311537 936917938 470322306 441117213 243813087 255324265 12696724 854288754 806520692 86012500 328564694 878537022 839751145 915142745 18140745 125518575 342802686 947890980 ...
result:
ok 100000 numbers
Test #17:
score: 0
Accepted
time: 3668ms
memory: 76424kb
input:
100000 FNVIO ><<=< ISCUB ><><> GQCGY ><>>< IIREF ><>>> LAWQL >><<< VDQNS <>><< ZDJDH <>>>= KAYMX >><<< KQWNL ><<<< MWVRW ><<<< FETOJ >=><< LEEOT >=><< ZGJPH <<><= VDPHC <>>>> VJRWA <<><> SCRPJ <>><< JBQCF >>>>> YWVGU <<<>< XGWNB <<<<> BTAWV ><><< RSMBD <<>>> KFBJX ><><< GPSZZ ><><< WMSOJ <<><< QLXDF...
output:
1 99999 17256472 629188600 994653422 292821735 911451747 83353224 313471011 405421054 346258483 928805941 779780412 28863579 29385371 263188556 923438024 483744622 815893954 359620773 119778186 363999506 944722253 608984733 934576938 654424456 495668524 619666932 294467430 975718913 171023568 124035...
result:
ok 100000 numbers
Test #18:
score: 0
Accepted
time: 3630ms
memory: 76508kb
input:
100000 LMPEM >>>>< TOLDK >>>>< JRYKL >=<>< WRTSU ==<=< TZPGR <<<>< BHJXB >><<> RABOA <>><> TXPJU ><>>< YVFBJ <<=>< NHATH >>><< CNZDF >><>= VHJJY >>>>< DOUAS >><>< GMMQA >><<> AMKPR >>>>< IKAET >>>>< MFRKW <><<< SSMLJ <<<<< YAMZX <><<< CCXTO >><<< QNAAD <>>>> XDHLM <>>>< BKGQR >>>>< UXXOM ><<>< ANGIJ...
output:
0 933308107 299928578 143136372 376251907 975068160 721593698 753716245 898914068 490205891 886874629 146781702 587935621 279193639 699856836 561537033 880030199 518890130 56000918 362873285 264834282 611906519 200388605 960190510 691501587 606436430 881745603 751535317 348317466 237651997 812697060...
result:
ok 100000 numbers
Test #19:
score: 0
Accepted
time: 3563ms
memory: 76356kb
input:
100000 GKZXQ >><<< KHLZG <><<> XOPSL <><<< BAIDJ >><<< ARFUW >=<<< SRWMZ ><<>< IXTCI ><<>> CUFJQ ><<<< POBFV ><>>= XZCXW <<<<< NYEWD ><><> CWOQS ><<>> VILXN >><<> AYMDC ><<<> MBCPI >>>>> CFRWC >><<> CXNGB ><<<> QNFZL ><><> PIGHX <><<< UUKUR <<<<< TUDZQ ><><> GILEV >><>= EGTTE >><<> RSKCL ><<>> LYCDJ...
output:
0 166507515 459156293 304072419 460723604 974806918 569354203 431542442 512958995 436405304 696400930 642914783 541251712 836652606 565059619 514610302 346747578 937985955 592127812 100884846 134893017 448171682 583736771 651700927 454623153 163064670 98018215 70402567 66918097 107584460 749714113 1...
result:
ok 100000 numbers
Test #20:
score: 0
Accepted
time: 3653ms
memory: 76408kb
input:
100000 BILQU ><><< EBKTE >><<> NKHCI <<>>> GKVMX >><<< GIWIC ><<<> MAJDU >>=>< YULTQ <<><< KUVIK ><<>> FHYGI >><>> JOFAK >=>>> WHJPB <=><> MOSVM >=<<> MDBWH <>><> VLLQC <<><> YQTQA <<<<> VZJNK <<><= TNHBE <>>>> OHYMP >><<> FQAOU ><><< LNWSW >><<< VBFVF <>><> OMQUC >><<> HCIUP >>><> MMZQH >><<> YJZWL...
output:
0 38401793 447045659 902564881 855486954 858682963 916341122 319325485 19812241 668526803 143151417 331148639 425925192 804865129 333676787 704794449 910479352 696417420 82040052 29985024 973090487 9476047 487918272 830170804 447737654 497561219 593481691 928465739 179957021 384533495 178611683 4766...
result:
ok 100000 numbers
Test #21:
score: 0
Accepted
time: 3615ms
memory: 76372kb
input:
100000 KSHEU ><><< LUTYV ><<<< MXQOI ><<>> NNMHY ><><< NZIPQ ><><< XMKMH <><>> DDFVV >>><< TMRIN <<><< YDSBB ==<>> GEIFO >><>< JRWVV ><<<< LXVTF ><<>> KFCQQ >>><< TVKCO ><<>< OHAGB >>><= PEVCO ><<>< LYCEB ><>>> NNNTN ><<>< EYYBZ ><<>< MPCCW ><>>< HTJKP ><><< LQQDT ><<>< WBTLI >><>= JRYTE ><<>> POITD...
output:
0 964094440 836003257 708459847 871957496 654344326 948234133 953935212 104979316 364845725 665219506 642340940 870161743 128194009 326925049 353939789 704216254 589740748 620536805 305640004 484148956 831968196 6769193 754098116 546127667 437282971 570088555 466566847 739533250 638265014 473500063 ...
result:
ok 100000 numbers
Test #22:
score: 0
Accepted
time: 3609ms
memory: 76364kb
input:
100000 IMBCQ <<>>> SLSQD <<<=> AEBES >>>>< HTEYK ><><> BRSCG ><<>> LDIEX <<><< BMEJV ><<>< LCKFQ <><>> IPIDE =<>=> IPSKI ><>>> IYLZC =<><> EOQKE ><>>> EAOOD >>=<> XGZUO <><<= RAVYT <><<< EVMYK ><><> GWXYP <<<<> UEVNV <><=< AQQOY ><><< NRJDS <<<>= HCNOG <><>> SULRW <<><< FXNYW ><><< NEJQZ <><=< LYWGI...
output:
0 666826810 289231209 635258529 546720275 543561692 384443596 63424828 510070428 21542771 129058559 151021435 187384460 692633074 922852987 414682697 568116010 769155697 91852932 392144234 495241700 671207649 143169942 467816836 792533501 612880812 687987052 299606463 754344297 139546526 882788940 4...
result:
ok 100000 numbers
Test #23:
score: 0
Accepted
time: 3593ms
memory: 76444kb
input:
100000 FNFJC >=>>> JBTYS >>=<< QVCYB <<><> TTGOO <>>>> CNNNE >=<<= HCQEM >>><< KTESX ><><< RLPVL <>><> CQADI ><><< NCZRF <><<> NTWBK <><>> OJUNY <>><< MHIDY >>>>< LFECL >>>>< ENNVS >=<<< YYXYK <<<<> BALXT >>><> JVXBJ ><<>< PTDBE ><>>> RCFNT <>><> ZPWFG <<=>> MSVDA ><<<> YJXSV <><<< DOVKD ><<>> DXSPO...
output:
0 93009970 219804152 844567284 891926848 279947250 689135271 860615218 13010915 929722006 847603974 484303861 136418364 827768488 46032089 429102220 810639676 270957951 53183964 293737892 477650398 234505706 517796197 156812171 966975447 945982240 982711670 726121039 576777787 297259995 372223803 55...
result:
ok 100000 numbers
Test #24:
score: 0
Accepted
time: 3622ms
memory: 76372kb
input:
100000 TPOQJ <<<<> XUUDN <<<>< YFAGQ <>>>< VWSWT <<<<> GITXC <><<< AYRDP ><>>< ZOXOZ <=>>= OQEEJ >>>>> LMMFK <>>>< YQMTZ <>=<< BAWDI >><>> TQUIE <><>> LQFOZ ><<<= XYJNB ><>>> ANPKA ><<>> XNAGO <>>>> AARCV >>>=> IMBOU <>><< ECQGU =><>< EWFDL <<<>> AFWTZ >>><< FKLNJ =><>< CEPMR >><<= DPBFC ><><> YIHUM...
output:
0 731820826 161250844 5585597 470134782 556060811 257099719 111798459 512206035 622445488 559050664 46611111 378388720 149248369 900197806 243792137 756773235 70170364 529089164 538199381 933788591 643539872 670120393 985010776 935645389 262590905 309790899 412774006 752230002 629492948 403174711 17...
result:
ok 100000 numbers
Test #25:
score: 0
Accepted
time: 3618ms
memory: 76372kb
input:
100000 QBQZL <><<> DLOQX ><<<< QFGSH >>>>> GXSNZ ><<<< RDDUT <>>=< WXVWY <<<=< VCCQL <>>=> YSTQR <<>=< DFUIN =><>< GEGVJ <>><< SDHHM >><>> HQFRU >><>< ZHMPJ <<=>> TVMYN ><><< RCXHI <><>> CIYCA >><<> KVATT <<>>< GUWBK <<<>> EUUKP ><<>> BHKJW >><<< XAIMU <>><> LBYQV >><>= FKLSD >>><> VUQIB <<<<> ATMAS...
output:
0 646701422 310542475 455998428 727671893 716649694 854302830 116778947 413591563 630505272 957959940 707160196 798797072 884778819 315551957 165825483 211983439 44654126 489986563 445117918 290339951 363429453 357974679 236558197 5060958 200582726 105877545 962523756 472161796 650269082 123320504 8...
result:
ok 100000 numbers
Test #26:
score: 0
Accepted
time: 1636ms
memory: 62072kb
input:
1 ZZZZZ =>=>>
output:
1
result:
ok 1 number(s): "1"