結果
| 問題 |
No.3117 Reversible Tile
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-04-20 12:58:35 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 169 ms / 3,000 ms |
| コード長 | 3,515 bytes |
| コンパイル時間 | 2,323 ms |
| コンパイル使用メモリ | 199,104 KB |
| 実行使用メモリ | 7,848 KB |
| 最終ジャッジ日時 | 2025-04-20 12:58:41 |
| 合計ジャッジ時間 | 4,944 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 24 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using int64 = long long;
const int MOD = 998244353;
const int INV2 = (MOD + 1) / 2; // 2^{-1} mod MOD
inline void addmod(int &a, int b) {
int s = a + b;
if (s >= MOD) s -= MOD;
a = s;
}
inline void submod(int &a, int b) {
int s = a - b;
if (s < 0) s += MOD;
a = s;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, M;
cin >> N >> M;
vector<int> A(N);
for (int &x : A) cin >> x;
const int OFF = N + 1; // 0 が配列中央に来るようオフセット
const int SZ = 2 * N + 3; // z ∈ [-(N+1), N+1]
/* dp[p][t][z] を 4 本の 1D 配列で持つ
p = 0/1 (現在の P_i), t = 0/1 (dot parity) */
vector<int> p0e(SZ), p0o(SZ), p1e(SZ), p1o(SZ);
vector<int> c0e(SZ), c0o(SZ), c1e(SZ), c1o(SZ);
p0e[OFF + 1] = 1; // i = 0 の初期 (z = 1, P_0 = 0, parity even)
for (int i = 1; i <= N; ++i) {
const int Ai = A[i - 1];
const int lowPrev = OFF - i;
const int highPrev = OFF + i;
const int lowCurr = OFF - (i + 1);
const int highCurr = OFF + (i + 1);
/* 配列クリア (次に使う範囲だけ) */
for (int idx = lowCurr; idx <= highCurr; ++idx)
c0e[idx] = c0o[idx] = c1e[idx] = c1o[idx] = 0;
for (int idx = lowPrev; idx <= highPrev; ++idx) {
int v;
/* p = 0, t even */
if ((v = p0e[idx])) {
addmod(c0e[idx + 1], v); // P_{i+1}=0
if (Ai) addmod(c1o[idx - 1], v); // P_{i+1}=1, parity flips
else addmod(c1e[idx - 1], v);
}
/* p = 0, t odd */
if ((v = p0o[idx])) {
addmod(c0o[idx + 1], v);
if (Ai) addmod(c1e[idx - 1], v);
else addmod(c1o[idx - 1], v);
}
/* p = 1, t even */
if ((v = p1e[idx])) {
if (Ai) addmod(c0o[idx + 1], v); else addmod(c0e[idx + 1], v);
addmod(c1e[idx - 1], v);
}
/* p = 1, t odd */
if ((v = p1o[idx])) {
if (Ai) addmod(c0e[idx + 1], v); else addmod(c0o[idx + 1], v);
addmod(c1o[idx - 1], v);
}
}
swap(p0e, c0e); swap(p0o, c0o);
swap(p1e, c1e); swap(p1o, c1o);
}
/* 2^{-N} mod MOD */
int pow2N = 1;
for (int i = 0; i < N; ++i) pow2N = (pow2N * 2LL) % MOD;
int inv2N = 1;
int e = MOD - 2, base = pow2N;
while (e) {
if (e & 1) inv2N = (int64)inv2N * base % MOD;
base = (int64)base * base % MOD;
e >>= 1;
}
int64 answer = 0;
for (int idx = OFF - (N + 1); idx <= OFF + (N + 1); ++idx) {
int d = idx - OFF;
int even = (p0e[idx] + p1e[idx]) % MOD;
int odd = (p0o[idx] + p1o[idx]) % MOD;
int Bd = even - odd;
if (Bd < 0) Bd += MOD;
if (Bd == 0) continue;
/* S(d) = ((d^2 - (N+1))/2) mod MOD */
int64 Sd = ( ( (int64)d * d - (N + 1) ) % MOD + MOD ) % MOD;
Sd = Sd * INV2 % MOD;
int64 powS = 1, baseS = Sd;
int m = M;
while (m) {
if (m & 1) powS = powS * baseS % MOD;
baseS = baseS * baseS % MOD;
m >>= 1;
}
answer = (answer + Bd * powS) % MOD;
}
answer = answer * inv2N % MOD;
cout << answer << '\n';
return 0;
}