QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#880727#9698. Twenty-twohos_lyricWA 1ms19884kbC++148.7kb2025-02-03 18:51:372025-02-03 18:51:39

Judging History

This is the latest submission verdict.

  • [2025-02-03 18:51:39]
  • Judged
  • Verdict: WA
  • Time: 1ms
  • Memory: 19884kb
  • [2025-02-03 18:51:37]
  • Submitted

answer

#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

using Int = long long;

template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")

////////////////////////////////////////////////////////////////////////////////
template <unsigned M_> struct ModInt {
  static constexpr unsigned M = M_;
  unsigned x;
  constexpr ModInt() : x(0U) {}
  constexpr ModInt(unsigned x_) : x(x_ % M) {}
  constexpr ModInt(unsigned long long x_) : x(x_ % M) {}
  constexpr ModInt(int x_) : x(((x_ %= static_cast<int>(M)) < 0) ? (x_ + static_cast<int>(M)) : x_) {}
  constexpr ModInt(long long x_) : x(((x_ %= static_cast<long long>(M)) < 0) ? (x_ + static_cast<long long>(M)) : x_) {}
  ModInt &operator+=(const ModInt &a) { x = ((x += a.x) >= M) ? (x - M) : x; return *this; }
  ModInt &operator-=(const ModInt &a) { x = ((x -= a.x) >= M) ? (x + M) : x; return *this; }
  ModInt &operator*=(const ModInt &a) { x = (static_cast<unsigned long long>(x) * a.x) % M; return *this; }
  ModInt &operator/=(const ModInt &a) { return (*this *= a.inv()); }
  ModInt pow(long long e) const {
    if (e < 0) return inv().pow(-e);
    ModInt a = *this, b = 1U; for (; e; e >>= 1) { if (e & 1) b *= a; a *= a; } return b;
  }
  ModInt inv() const {
    unsigned a = M, b = x; int y = 0, z = 1;
    for (; b; ) { const unsigned q = a / b; const unsigned c = a - q * b; a = b; b = c; const int w = y - static_cast<int>(q) * z; y = z; z = w; }
    assert(a == 1U); return ModInt(y);
  }
  ModInt operator+() const { return *this; }
  ModInt operator-() const { ModInt a; a.x = x ? (M - x) : 0U; return a; }
  ModInt operator+(const ModInt &a) const { return (ModInt(*this) += a); }
  ModInt operator-(const ModInt &a) const { return (ModInt(*this) -= a); }
  ModInt operator*(const ModInt &a) const { return (ModInt(*this) *= a); }
  ModInt operator/(const ModInt &a) const { return (ModInt(*this) /= a); }
  template <class T> friend ModInt operator+(T a, const ModInt &b) { return (ModInt(a) += b); }
  template <class T> friend ModInt operator-(T a, const ModInt &b) { return (ModInt(a) -= b); }
  template <class T> friend ModInt operator*(T a, const ModInt &b) { return (ModInt(a) *= b); }
  template <class T> friend ModInt operator/(T a, const ModInt &b) { return (ModInt(a) /= b); }
  explicit operator bool() const { return x; }
  bool operator==(const ModInt &a) const { return (x == a.x); }
  bool operator!=(const ModInt &a) const { return (x != a.x); }
  friend std::ostream &operator<<(std::ostream &os, const ModInt &a) { return os << a.x; }
};
////////////////////////////////////////////////////////////////////////////////

constexpr unsigned MO = 998244353;
using Mint = ModInt<MO>;


void exper() {
  // m chmins, n chmaxs
  for (int m = 1; m <= 3; ++m) for (int n = 1; n <= 2; ++n) {
    string ops = string(m, '0') + string(n, '1');
    do {
      printf("ops = %s\n", ops.c_str());
      vector<int> cs(m + n);
      for (int i = 0; i < m + n; ++i) cs[i] = i;
      do {
        // chmin incr.
        if ([&]() -> bool {
          int cm = -1;
          for (const int c : cs) if (ops[c] == '0') if (!chmax(cm, c)) return false;
          return true;
        }()) {
          int l = -1, r = m + n;
          int z = -1;
          for (int i = m + n; --i >= 0; ) {
            if (ops[cs[i]] == '0') {
              chmin(r, cs[i]);
              if (l > r) { z = l; break; }
            } else {
              chmax(l, cs[i]);
              if (l > r) { z = r; break; }
            }
          }
          int cnt = 0;
          for (int i = 0; i < m + n; ++i) {
            if (ops[cs[i]] == '0') {
              printf("%s[%d] ", string((n - cnt) * 2, ' ').c_str(), cs[i]);
              cnt = 0;
            } else {
              printf("%d ", cs[i]);
              ++cnt;
            }
          }
          printf("%s : ", string((n - cnt) * 2, ' ').c_str());
          if (l > r) {
            printf("%d", z);
          } else {
            printf("[%d,%d]", l, r);
          }
          puts("");
          
          // for each chmax, chmined in the nearest future
          int mx = -1;
          for (int i = 0; i < m + n; ++i) if (ops[cs[i]] == '1') {
            int c = cs[i];
            for (int j = i + 1; j < m + n; ++j) if (ops[cs[j]] == '0') {
              if (chmin(c, cs[j])) break;
            }
            chmax(mx, c);
          }
          if (l > r) assert(z == mx);
        }
      } while (next_permutation(cs.begin(), cs.end()));
      puts("");
      fflush(stdout);
    } while (next_permutation(ops.begin(), ops.end()));
  }
}
/*
sample
ops = 0101
    [0] 1   [2] 3    : 3
    [0] 1 3 [2]      : 2
    [0]     [2] 1 3  : 3
    [0]     [2] 3 1  : 3
    [0] 3 1 [2]      : 2
    [0] 3   [2] 1    : 2
1   [0]     [2] 3    : 3
1   [0] 3   [2]      : 2
1 3 [0]     [2]      : 0
3   [0] 1   [2]      : 1
3   [0]     [2] 1    : 1
3 1 [0]     [2]      : 0
*/

/*
  backward
  chmin(-, c): [-INF, c]
  chmax(-, d): [d, +INF]
  can ignore the positions where all intervals intersect
  
  chmins: C[0] <= C[1] <= ... <= C[M-1]
  chmin incr.
  0 = i[0] < i[1] < ... < i[k-1] < M
  single chmax(-, d)
    insert at: ..., chmin(-, C[i[l-1]]), chmax(-, d), chmin(-, C[i[l]]), ...
    if d <= C[i[l]]
        [l, r] = [d, C[i[l]]] ~~> finally >= d
        other chmax ==> possibly z determined earlier with larger l or with r
    if d >  C[i[l]]
        [l, r] = [*, C[i[l]]] ~~> z = C[i[l]]
        other chmax ==> possibly z determined earlier with larger r
  can assume all chmins are used
  for each chmax(-, d), select d or smaller value in C, then take their max
  
  sample
    for [0, 3), chmax(-, d) with d = 2 or 3
    for [1, 5), chmax(-, d) with d = 2 or 4 or 5
    22222, 24444, 25555, 33322, 34444, 35555
  
  decision
    consider min = x
    can use any available chmax, so check if:
      - OK already
      - chmax(-, x) available
      - x \in C, chmax(-, d) available s.t. x < d
    divide, recurse
  
  counting
    dp[x][l][r]: min >= x, (l, r)
    transition: all positions of x
      l = u[0] -> u[1] -> ... -> u[p-1] -> u[p] = r
*/

constexpr int MAX = 160;

int N, M, K;
vector<int> C;
vector<int> L, R, D;

Mint dp[MAX][MAX][MAX];
bool can[MAX];
Mint sub[MAX];

int main() {
  // exper();
  
  for (; ~scanf("%d%d%d", &N, &M, &K); ) {
    for (int u = 1; u <= N; ++u) {
      scanf("%*d");
    }
    C.resize(M);
    for (int i = 0; i < M; ++i) {
      scanf("%d", &C[i]);
    }
    sort(C.begin(), C.end());
    L.resize(K);
    R.resize(K);
    D.resize(K);
    for (int k = 0; k < K; ++k) {
      scanf("%d%d%d", &L[k], &R[k], &D[k]);
    }
    
    memset(dp, 0, sizeof(dp));
    for (int l = N; l >= 0; --l) {
      dp[N + 1][l][l + 1] = 1;
    }
    for (int x = N; x >= 0; --x) {
      bool inC = false;
      for (int i = 0; i < M; ++i) inC = inC || (C[i] == x);
      for (int l = N; l >= 0; --l) for (int r = l + 1; r <= N + 1; ++r) {
        for (int u = l; u <= r; ++u) can[u] = false;
        can[l] = can[r] = true;
        for (int k = 0; k < K; ++k) if (l < L[k] && R[k] < r) {
          if (inC ? (D[k] >= x) : (D[k] == x)) {
            for (int u = L[k]; u <= R[k]; ++u) can[u] = true;
          }
        }
        for (int u = l; u <= r; ++u) sub[u] = 0;
        sub[l] = 1;
        for (int u = l; u < r; ++u) if (sub[u]) {
          for (int v = u + 1; v <= r; ++v) if (can[v]) {
            sub[v] += sub[u] * dp[x + 1][u][v];
          }
        }
        dp[x][l][r] += sub[r];
      }
    }
    printf("%u\n", dp[0][0][N + 1].x);
  }
  return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 1ms
memory: 19884kb

input:

5 2 2
4 1 3 5 2
2 4
1 3 3
2 5 5

output:

6

result:

ok 1 number(s): "6"

Test #2:

score: -100
Wrong Answer
time: 1ms
memory: 19836kb

input:

13 2 1
12 13 4 12 9 12 11 3 13 1 3 8 10
3 9
6 7 10

output:

0

result:

wrong answer 1st numbers differ - expected: '3', found: '0'