結果
問題 | No.1241 Eternal Tours |
ユーザー | hitonanode |
提出日時 | 2021-07-25 00:30:16 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 396 ms / 6,000 ms |
コード長 | 14,080 bytes |
コンパイル時間 | 2,966 ms |
コンパイル使用メモリ | 116,908 KB |
実行使用メモリ | 32,984 KB |
最終ジャッジ日時 | 2024-07-20 06:17:51 |
合計ジャッジ時間 | 9,255 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 1 ms
5,376 KB |
testcase_02 | AC | 101 ms
11,520 KB |
testcase_03 | AC | 2 ms
5,376 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 2 ms
5,376 KB |
testcase_06 | AC | 2 ms
5,376 KB |
testcase_07 | AC | 2 ms
5,376 KB |
testcase_08 | AC | 2 ms
5,376 KB |
testcase_09 | AC | 1 ms
5,376 KB |
testcase_10 | AC | 2 ms
5,376 KB |
testcase_11 | AC | 2 ms
5,376 KB |
testcase_12 | AC | 2 ms
5,376 KB |
testcase_13 | AC | 2 ms
5,376 KB |
testcase_14 | AC | 181 ms
8,064 KB |
testcase_15 | AC | 2 ms
5,376 KB |
testcase_16 | AC | 46 ms
5,376 KB |
testcase_17 | AC | 393 ms
32,900 KB |
testcase_18 | AC | 394 ms
14,080 KB |
testcase_19 | AC | 347 ms
11,788 KB |
testcase_20 | AC | 3 ms
5,376 KB |
testcase_21 | AC | 8 ms
5,376 KB |
testcase_22 | AC | 370 ms
22,232 KB |
testcase_23 | AC | 13 ms
5,376 KB |
testcase_24 | AC | 2 ms
5,376 KB |
testcase_25 | AC | 1 ms
5,376 KB |
testcase_26 | AC | 2 ms
5,376 KB |
testcase_27 | AC | 2 ms
5,376 KB |
testcase_28 | AC | 212 ms
11,520 KB |
testcase_29 | AC | 208 ms
11,520 KB |
testcase_30 | AC | 262 ms
11,520 KB |
testcase_31 | AC | 177 ms
7,424 KB |
testcase_32 | AC | 396 ms
32,984 KB |
testcase_33 | AC | 372 ms
12,500 KB |
testcase_34 | AC | 358 ms
11,520 KB |
testcase_35 | AC | 350 ms
11,520 KB |
testcase_36 | AC | 2 ms
5,376 KB |
testcase_37 | AC | 2 ms
5,376 KB |
testcase_38 | AC | 385 ms
12,500 KB |
testcase_39 | AC | 367 ms
12,008 KB |
testcase_40 | AC | 369 ms
11,520 KB |
testcase_41 | AC | 264 ms
32,980 KB |
testcase_42 | AC | 228 ms
12,012 KB |
testcase_43 | AC | 222 ms
11,520 KB |
ソースコード
#include <atcoder/modint> #ifndef ATCODER_INTERNAL_BITOP_HPP #define ATCODER_INTERNAL_BITOP_HPP 1 #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` constexpr int bsf_constexpr(unsigned int n) { int x = 0; while (!(n & (1 << x))) 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 #endif // ATCODER_INTERNAL_BITOP_HPP #ifndef ATCODER_CONVOLUTION_HPP #define ATCODER_CONVOLUTION_HPP 1 #include <algorithm> #include <array> #include <cassert> #include <type_traits> #include <vector> // #include "atcoder/internal_bit" // #include "atcoder/modint" namespace atcoder { namespace internal { template <class mint, int g = internal::primitive_root<mint::mod()>, internal::is_static_modint_t<mint>* = nullptr> struct fft_info { static constexpr int rank2 = bsf_constexpr(mint::mod() - 1); std::array<mint, rank2 + 1> root; // root[i]^(2^i) == 1 std::array<mint, rank2 + 1> iroot; // root[i] * iroot[i] == 1 std::array<mint, std::max(0, rank2 - 2 + 1)> rate2; std::array<mint, std::max(0, rank2 - 2 + 1)> irate2; std::array<mint, std::max(0, rank2 - 3 + 1)> rate3; std::array<mint, std::max(0, rank2 - 3 + 1)> irate3; fft_info() { root[rank2] = mint(g).pow((mint::mod() - 1) >> rank2); iroot[rank2] = root[rank2].inv(); for (int i = rank2 - 1; i >= 0; i--) { 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]; } } { mint 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]; } } } }; template <class mint, internal::is_static_modint_t<mint>* = nullptr> void butterfly(std::vector<mint>& a) { int n = int(a.size()); int h = internal::ceil_pow2(n); static const fft_info<mint> info; int len = 0; // a[i, i+(n>>len), i+2*(n>>len), ..] is transformed while (len < h) { if (h - len == 1) { int p = 1 << (h - len - 1); mint rot = 1; for (int s = 0; s < (1 << len); s++) { int offset = s << (h - len); for (int i = 0; i < p; i++) { auto l = a[i + offset]; auto r = a[i + offset + p] * rot; a[i + offset] = l + r; a[i + offset + p] = l - r; } if (s + 1 != (1 << len)) rot *= info.rate2[bsf(~(unsigned int)(s))]; } len++; } else { // 4-base int p = 1 << (h - len - 2); mint rot = 1, imag = info.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++) { auto mod2 = 1ULL * mint::mod() * mint::mod(); auto a0 = 1ULL * a[i + offset].val(); auto a1 = 1ULL * a[i + offset + p].val() * rot.val(); auto a2 = 1ULL * a[i + offset + 2 * p].val() * rot2.val(); auto a3 = 1ULL * a[i + offset + 3 * p].val() * rot3.val(); auto a1na3imag = 1ULL * mint(a1 + mod2 - a3).val() * imag.val(); auto 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); } if (s + 1 != (1 << len)) rot *= info.rate3[bsf(~(unsigned int)(s))]; } len += 2; } } } template <class mint, internal::is_static_modint_t<mint>* = nullptr> void butterfly_inv(std::vector<mint>& a) { int n = int(a.size()); int h = internal::ceil_pow2(n); static const fft_info<mint> info; int len = h; // a[i, i+(n>>len), i+2*(n>>len), ..] is transformed while (len) { if (len == 1) { int p = 1 << (h - len); mint irot = 1; for (int s = 0; s < (1 << (len - 1)); s++) { int offset = s << (h - len + 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()) * irot.val(); ; } if (s + 1 != (1 << (len - 1))) irot *= info.irate2[bsf(~(unsigned int)(s))]; } len--; } else { // 4-base int p = 1 << (h - len); mint irot = 1, iimag = info.iroot[2]; for (int s = 0; s < (1 << (len - 2)); s++) { mint irot2 = irot * irot; mint irot3 = irot2 * irot; int offset = s << (h - len + 2); for (int i = 0; i < p; i++) { auto a0 = 1ULL * a[i + offset + 0 * p].val(); auto a1 = 1ULL * a[i + offset + 1 * p].val(); auto a2 = 1ULL * a[i + offset + 2 * p].val(); auto a3 = 1ULL * a[i + offset + 3 * p].val(); auto a2na3iimag = 1ULL * mint((mint::mod() + a2 - a3) * iimag.val()).val(); a[i + offset] = a0 + a1 + a2 + a3; a[i + offset + 1 * p] = (a0 + (mint::mod() - a1) + a2na3iimag) * irot.val(); a[i + offset + 2 * p] = (a0 + a1 + (mint::mod() - a2) + (mint::mod() - a3)) * irot2.val(); a[i + offset + 3 * p] = (a0 + (mint::mod() - a1) + (mint::mod() - a2na3iimag)) * irot3.val(); } if (s + 1 != (1 << (len - 2))) irot *= info.irate3[bsf(~(unsigned int)(s))]; } len -= 2; } } } template <class mint, internal::is_static_modint_t<mint>* = nullptr> std::vector<mint> convolution_naive(const std::vector<mint>& a, const std::vector<mint>& b) { int n = int(a.size()), m = int(b.size()); std::vector<mint> ans(n + m - 1); if (n < m) { for (int j = 0; j < m; j++) { for (int i = 0; i < n; i++) { ans[i + j] += a[i] * b[j]; } } } else { for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { ans[i + j] += a[i] * b[j]; } } } return ans; } template <class mint, internal::is_static_modint_t<mint>* = nullptr> std::vector<mint> convolution_fft(std::vector<mint> a, std::vector<mint> b) { int n = int(a.size()), m = int(b.size()); 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; } } // 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) return convolution_naive(a, b); return internal::convolution_fft(a, b); } template <class mint, internal::is_static_modint_t<mint>* = nullptr> std::vector<mint> convolution(const std::vector<mint>& a, const std::vector<mint>& b) { int n = int(a.size()), m = int(b.size()); if (!n || !m) return {}; if (std::min(n, m) <= 60) return convolution_naive(a, b); return internal::convolution_fft(a, b); } 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 #endif // ATCODER_CONVOLUTION_HPP #include <iostream> using namespace std; using mint = atcoder::modint998244353; template <typename MODINT> void ntt2d(std::vector<std::vector<MODINT>> &mat) { for (auto &vec : mat) atcoder::internal::butterfly(vec); int h = mat.size(), w = mat[0].size(); for (int j = 0; j < w; j++) { std::vector<MODINT> v(h); for (int i = 0; i < h; i++) v[i] = mat[i][j]; atcoder::internal::butterfly(v); for (int i = 0; i < h; i++) mat[i][j] = v[i]; } } template <typename MODINT> void ntt2dinv(std::vector<std::vector<MODINT>> &mat) { int h = mat.size(), w = mat[0].size(); for (int j = 0; j < w; j++) { std::vector<MODINT> v(h); for (int i = 0; i < h; i++) v[i] = mat[i][j]; atcoder::internal::butterfly_inv(v); for (int i = 0; i < h; i++) mat[i][j] = v[i]; } for (auto &vec : mat) atcoder::internal::butterfly_inv(vec); MODINT ninv = MODINT(h * w).inv(); for (auto &vec : mat) { for (auto &x : vec) { x *= ninv; } } } int main() { int X, Y; long long T; int a, b, c, d; cin >> X >> Y >> T >> a >> b >> c >> d; vector dp(1 << (X + 1), vector<mint>(1 << (Y + 1))); dp[a][b] = 1; dp[(1 << (X + 1)) - a][(1 << (Y + 1)) - b] = 1; dp[(1 << (X + 1)) - a][b] = -1; dp[a][(1 << (Y + 1)) - b] = -1; vector trans(1 << (X + 1), vector<mint>(1 << (Y + 1))); trans[0][0] = trans[0][1] = trans[0][(1 << (Y + 1)) - 1] = trans[1][0] = trans[(1 << (X + 1)) - 1][0] = 1; ntt2d(dp); ntt2d(trans); for (size_t i = 0; i < dp.size(); i++) { for (size_t j = 0; j < dp[i].size(); j++) { dp[i][j] *= trans[i][j].pow(T); } } ntt2dinv(dp); cout << dp[c][d].val() << '\n'; }