結果
| 問題 |
No.3119 A Little Cheat
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-04-18 21:47:06 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
MLE
|
| 実行時間 | - |
| コード長 | 3,518 bytes |
| コンパイル時間 | 1,890 ms |
| コンパイル使用メモリ | 198,872 KB |
| 実行使用メモリ | 814,524 KB |
| 最終ジャッジ日時 | 2025-04-18 21:47:16 |
| 合計ジャッジ時間 | 9,658 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | -- * 3 |
| other | MLE * 1 -- * 48 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MOD = 998244353;
// Fast exponentiation modulo MOD
ll modpow(ll a, ll e) {
ll r = 1;
while (e > 0) {
if (e & 1) r = r * a % MOD;
a = a * a % MOD;
e >>= 1;
}
return r;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, M;
cin >> N >> M;
vector<int> A(N);
for(int i = 0; i < N; i++) {
cin >> A[i];
}
// Precompute sum_A = sum_{i=1..N} (M - A[i]) mod
ll sumA = 0;
for (int i = 0; i < N; i++) {
sumA = (sumA + (M - A[i])) % MOD;
}
// Term1 = M^{N-1} * sumA (sum of original matches over all B)
ll term1 = modpow(M, N - 1) * sumA % MOD;
// If N == 1, no swaps possible => answer = term1
if (N == 1) {
cout << term1 << "\n";
return 0;
}
// DP to count D = # of B with no swap giving positive gain
// dp[v] = number of ways for prefix ending with B_i = v
vector<ll> dp(M+2, 1), nxt(M+2, 0), pref(M+2, 0), diff(M+3, 0);
// Initial dp for i=1: all 1
ll S = M; // total sum of dp
for(int i = 0; i < N-1; i++){
int alpha = A[i], beta = A[i+1];
// Build prefix sums of dp
pref[0] = 0;
for(int v = 1; v <= M; v++){
pref[v] = (pref[v-1] + dp[v]) % MOD;
}
// reset diff array
fill(diff.begin(), diff.end(), 0LL);
if (alpha < beta) {
// T = sum dp[v] for v in (alpha, beta]
ll T = (pref[beta] - pref[alpha] + MOD) % MOD;
// From u with h(u)=1: add T to all v
diff[1] = (diff[1] + T) % MOD;
diff[M+1] = (diff[M+1] - T + MOD) % MOD;
// From u with h(u)=0: sum = S-T, add to v in [1..alpha] and [beta+1..M]
ll U = (S - T + MOD) % MOD;
// [1..alpha]
diff[1] = (diff[1] + U) % MOD;
diff[alpha+1] = (diff[alpha+1] - U + MOD) % MOD;
// [beta+1..M]
diff[beta+1] = (diff[beta+1] + U) % MOD;
diff[M+1] = (diff[M+1] - U + MOD) % MOD;
}
else if (alpha > beta) {
// Usum = sum dp[v] for v in [1..beta] and [alpha+1..M]
ll U1 = pref[beta];
ll U2 = (S - pref[alpha] + MOD) % MOD;
ll U = (U1 + U2) % MOD;
// From u in U-group: add U to all v
diff[1] = (diff[1] + U) % MOD;
diff[M+1] = (diff[M+1] - U + MOD) % MOD;
// From u in mid ((beta..alpha]): sum = S-U, add to v in [beta+1..alpha]
ll mid = (S - U + MOD) % MOD;
diff[beta+1] = (diff[beta+1] + mid) % MOD;
diff[alpha+1] = (diff[alpha+1] - mid + MOD) % MOD;
}
else {
// alpha == beta: all transitions allowed, dp[i+1][*] = S
diff[1] = (diff[1] + S) % MOD;
diff[M+1] = (diff[M+1] - S + MOD) % MOD;
}
// Build nxt from diff by prefix sums
ll acc = 0;
for(int v = 1; v <= M; v++){
acc = (acc + diff[v]) % MOD;
nxt[v] = acc;
}
// swap dp and nxt, update S
S = 0;
for(int v = 1; v <= M; v++){
dp[v] = nxt[v];
S = (S + dp[v]) % MOD;
}
}
ll D = S; // number of B with no positive swap gain
// Total B = M^N; C1 = total - D
ll total = modpow(M, N);
ll C1 = (total - D + MOD) % MOD;
ll answer = (term1 + C1) % MOD;
cout << answer << "\n";
return 0;
}