QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#145319#6410. Classical DP Problemnhuang685WA 1ms3848kbC++205.4kb2023-08-22 05:41:152023-08-22 05:41:16

Judging History

你现在查看的是最新测评结果

  • [2023-08-22 05:41:16]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:3848kb
  • [2023-08-22 05:41:15]
  • 提交

answer

/**
 * @file qoj6410-1.cpp
 * @author n685
 * @brief
 * @date 2023-08-21
 *
 *
 */
#include <bits/stdc++.h>

#ifdef LOCAL
std::ifstream cin;
std::ofstream cout;
using std::cerr;
#else
using std::cin;
using std::cout;
#define cerr                                                                   \
  if (false)                                                                   \
  std::cerr
#endif

#ifdef LOCAL
#include "dd/debug.h"
#define dbg(...) lineInfo(__LINE__, #__VA_ARGS__), dbg1(__VA_ARGS__)
#define dbgR(...) lineInfo(__LINE__, #__VA_ARGS__), dbg2(__VA_ARGS__)
void nline() { cerr << '\n'; }
#else
#define dbg(...) 42
#define dbgR(...) 420
void nline() {}
#endif

template <class T> constexpr std::pair<T, T> exEucl(T a, T b) {
  if (a < b) {
    // auto [x, y] = exEucl(b, a);
    T x, y;
    std::tie(x, y) = exEucl(b, a);
    return {y, x};
  }
  if (b == 0) {
    assert(a == 1);
    return {1, 0};
  }
  // auto [x, y] = exEucl(b, a % b);
  T x, y;
  std::tie(x, y) = exEucl(b, a % b);
  return {y, x - (a / b) * y};
}
template <
    class T, class U,
    typename std::enable_if<std::is_integral<U>::value, bool>::type = true>
constexpr T binpow(const T &val, U b) {
  // 0^0 = 1
  T res = 1, a = val;
  while (b > 0) {
    if (b % 2 == 1)
      res *= a;
    a *= a;
    b /= 2;
  }
  return res;
}

template <class Md, class V = int64_t> struct Mod {
  using T = typename std::decay<decltype(Md::value)>::type;
  T val = 0;

  template <class U> static constexpr T normalize(U val) {
    if (val <= -Md::value || Md::value <= val)
      val %= Md::value;
    if (val < 0)
      val += Md::value;
    return static_cast<T>(val);
  }

  constexpr Mod() : val(0) {}
  template <class U, typename std::enable_if<std::is_integral<U>::value,
                                             bool>::type = true>
  constexpr Mod(U _val) {
    val = normalize(_val);
  }

  // addition
  constexpr Mod &operator+=(Mod b) {
    val += b.val;
    if (val >= Md::value)
      val -= Md::value;
    return *this;
  }
  friend constexpr Mod operator+(Mod a, Mod b) { return (a += b); }
  constexpr Mod &operator++() { return (*this += 1); }
  constexpr Mod operator++(int) {
    Mod res = *this;
    ++(*this);
    return res;
  }

  // subtraction
  constexpr Mod &operator-=(Mod b) {
    val -= b.val;
    if (val < 0)
      val += Md::value;
    return *this;
  }
  friend constexpr Mod operator-(Mod a, Mod b) { return (a -= b); }
  constexpr Mod &operator--() { return (*this -= 1); }
  constexpr Mod operator--(int) {
    Mod res = *this;
    --(*this);
    return res;
  }

  // multiplication
  constexpr Mod &operator*=(Mod b) {
    val = static_cast<T>(static_cast<V>(val) * b.val % Md::value);
    return *this;
  }
  friend constexpr Mod operator*(Mod a, Mod b) { return (a *= b); }

  template <class U> constexpr Mod binpow(U b) const {
    return ::binpow(*this, b);
  }
  constexpr Mod inv() const {
    return Mod(exEucl(static_cast<V>(val), static_cast<V>(Md::value)).first);
    // return binpow(Md::value - 2);
  }

  // comparison
  constexpr bool operator==(Mod b) const { return (val == b.val); }
  // constexpr auto operator<=>(const Mod &b) const = default;
  constexpr bool operator!=(Mod b) const { return (val != b.val); }
  constexpr bool operator<(Mod b) const { return (val < b.val); }
  constexpr bool operator>(Mod b) const { return (val > b.val); }
  constexpr bool operator<=(Mod b) const { return (val <= b.val); }
  constexpr bool operator>=(Mod b) const { return (val >= b.val); }

  // io
  friend std::istream &operator>>(std::istream &in, Mod &a) {
    V v;
    in >> v;
    a = Mod(v);
    return in;
  }
  friend std::ostream &operator<<(std::ostream &out, const Mod &a) {
    out << a.val;
    return out;
  }

  // conversion
  explicit constexpr operator T() const { return val; }
  constexpr const T &operator()() const { return val; }
  constexpr Mod operator-() const { return Mod(-val); }
};

constexpr int MOD = 998244353;
using Mint = Mod<std::integral_constant<std::decay<decltype(MOD)>::type, MOD>>;

int main() {
#ifdef LOCAL
  cin.open("input.txt");
  cout.rdbuf()->pubsetbuf(0, 0);
  cout.open("output.txt");
#else
  cin.tie(nullptr)->sync_with_stdio(false);
#endif

  int n;
  cin >> n;

  std::vector<int> a(n + 1);
  for (int i = 1; i <= n; ++i)
    cin >> a[i];
  std::reverse(a.begin() + 1, a.end());

  int k = n;
  for (int i = 1; i <= n - 1; ++i)
    if (a[i] >= i && a[i + 1] < i + 1) {
      k = i;
      break;
    }

  Mint ans = 0;
  if (k != n) {
    auto solve = [&]() {
      int t = a[k + 1];
      std::vector<std::vector<Mint>> dp(k + 1, std::vector<Mint>(t + 1));
      dp[0][0] = 1;
      for (int i = 1; i <= k; ++i) {
        for (int j = 0; j <= t; ++j) {
          dp[i][j] += dp[i - 1][j] * (a[i] - (t - j));
          if (j > 0)
            dp[i][j] += dp[i - 1][j - 1] * (t - (j - 1));
        }
      }
      ans += dp[k][t];
    };
    solve();
    std::vector<int> na(n + 1, n);
    for (int i = n; i > a[1]; --i)
      na[i] = 0;
    for (int i = 1; i <= n - 1; ++i) {
      for (int j = a[i]; j > a[i + 1]; --j)
        na[j] = i;
    }
    a.swap(na);
    solve();
  }
  Mint f = 1;
  for (int i = 2; i <= k; ++i)
    f *= i;
  if (k == n)
    cout << k << ' ' << f << '\n';
  else
    cout << k << ' ' << ans - f << '\n';
}

詳細信息

Test #1:

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

input:

3
1 2 3

output:

2 6

result:

ok 2 number(s): "2 6"

Test #2:

score: 0
Accepted
time: 1ms
memory: 3596kb

input:

1
1

output:

1 1

result:

ok 2 number(s): "1 1"

Test #3:

score: 0
Accepted
time: 1ms
memory: 3624kb

input:

2
1 1

output:

1 2

result:

ok 2 number(s): "1 2"

Test #4:

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

input:

2
2 2

output:

2 2

result:

wrong answer 2nd numbers differ - expected: '6', found: '2'