結果

問題 No.3119 A Little Cheat
ユーザー Nzt3
提出日時 2025-04-15 16:51:30
言語 C++23
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 54 ms / 2,000 ms
コード長 2,764 bytes
コンパイル時間 3,540 ms
コンパイル使用メモリ 281,264 KB
実行使用メモリ 7,848 KB
最終ジャッジ日時 2025-04-15 16:53:45
合計ジャッジ時間 7,228 ms
ジャッジサーバーID
(参考情報)
judge5 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 52
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int MOD = 998244353;

void add(ll &a, ll b) { a = (a + b) % MOD; }

int main() {
  cin.tie(0)->sync_with_stdio(0);
  int N, M;
  cin >> N >> M;
  vector A(N, 0);
  for (auto &i : A) cin >> i;
  vector powM(N + 1, 0ll);
  powM[0] = 1;
  for (int i = 0; i < N; i++) {
    powM[i + 1] = powM[i] * M % MOD;
  }
  using al4 = array<ll, 4>;
  al4 dp;
  ll ans = 0;
  dp[0] = min(A[0], A[1]);
  dp[1] = max(A[0], A[1]) - min(A[0], A[1]);
  dp[2] = M - max(A[0], A[1]);
  dp[3] = 0;
  add(ans, (M - A[0]) * powM[N - 1]);
  A.push_back(0);
  for (int i = 1; i < N; i++) {
    al4 ndp = {0, 0, 0, 0};
    al4 m1 = {0, min(A[i - 1], A[i]), max(A[i - 1], A[i]), M},
        m2 = {0, min(A[i], A[i + 1]), max(A[i], A[i + 1]), M};
    ll pM = powM[N - 1 - i];
    // swap操作の有無と寄与の計算
    if (A[i - 1] < A[i]) {
      // swap: (2,1),(0,1)
      // +1  : (0,2),(1,2),(2,2)
      // none: (0,0),(1,0),(1,1),(2,0)
      for (int f = 0; f < 3; f++) {
        for (int s = 0; s < 3; s++) {
          if ((f == 2 && s == 1) || (f == 0 && s == 1)) {
            ll c = m1[s + 1] - m1[s];
            add(ans, dp[f] * c % MOD * pM);
            add(ndp[3], dp[f] * c);
          } else if (s == 2) {
            for (int t = 0; t < 3; t++) {
              ll c = max(0ll, min(m1[s + 1], m2[t + 1]) - max(m1[s], m2[t]));
              add(ans, dp[f] * c % MOD * pM);
              add(ndp[t], dp[f] * c);
            }
          } else {
            for (int t = 0; t < 3; t++) {
              ll c = max(0ll, min(m1[s + 1], m2[t + 1]) - max(m1[s], m2[t]));
              add(ndp[t], dp[f] * c);
            }
          }
        }
      }
    } else {
      // swap: (1,0),(1,2)
      // +1  : (0,1),(0,2),(1,1),(1,2),(2,2)
      // none: (0,0),(2,0)
      for (int f = 0; f < 3; f++) {
        for (int s = 0; s < 3; s++) {
          if ((f == 1 && s == 0) || (f == 1 && s == 2)) {
            ll c = m1[s + 1] - m1[s];
            add(ans, dp[f] * c % MOD * pM % MOD * (1 + (s == 2)));
            add(ndp[3], dp[f] * c);
          } else if (s != 0) {
            for (int t = 0; t < 3; t++) {
              ll c = max(0ll, min(m1[s + 1], m2[t + 1]) - max(m1[s], m2[t]));
              add(ans, dp[f] * c % MOD * pM);
              add(ndp[t], dp[f] * c);
            }
          } else {
            for (int t = 0; t < 3; t++) {
              ll c = max(0ll, min(m1[s + 1], m2[t + 1]) - max(m1[s], m2[t]));
              add(ndp[t], dp[f] * c);
            }
          }
        }
      }
    }
    // 既にswap操作を使っている
    add(ans, dp[3] * (M - A[i]) % MOD * pM);
    add(ndp[3], dp[3] * M);
    for (int j = 0; j < 4; j++) dp[j] = ndp[j];
  }
  cout << ans << '\n';
}
0