結果

問題 No.3371 Add Insert Operations
コンテスト
ユーザー areik
提出日時 2025-11-17 23:07:25
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 217 ms / 2,000 ms
コード長 2,347 bytes
コンパイル時間 4,475 ms
コンパイル使用メモリ 265,380 KB
実行使用メモリ 57,112 KB
最終ジャッジ日時 2025-11-17 23:07:45
合計ジャッジ時間 8,326 ms
ジャッジサーバーID
(参考情報)
judge4 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 36
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;

using isize = size_t;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
using f64 = long double;
using p2 = pair<i64, i64>;
using el = tuple<i64, i64, i64>;
using mint = atcoder::modint998244353;

void _main();
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(18);
  _main();
}

p2 op(p2 a, p2 b) {return min(a, b);}
p2 e() {return {1e18, 1e18};}
vector<i64> g[200000];
vector<mint> fac(300000, 1), finv(300000, 1), inv(300000, 0);
pair<i64, mint> dfs(i64 v) {
  i64 siz = 0;
  mint res = 1;
  for (i64 nv : g[v]) {
    auto [ns, p] = dfs(nv);
    res *= fac[siz + ns] * finv[siz] * finv[ns] * p;
    siz += ns;
  }
  siz++;
  return {siz, res};
}
void _main() {
  inv[1] = 1;
  i64 mod = 998244353;
  for (i64 i = 2; i < fac.size(); i++) {
    fac[i] = fac[i - 1] * i;
    inv[i] = -inv[mod % i] * (mod / i);
    finv[i] = finv[i - 1] * inv[i];
  }
  i64 n;
  cin >> n;
  vector<i64> a(n);
  for (i64 i = 0; i < n; i++) {
    cin >> a[i];
  }
  atcoder::segtree<p2, op, e> seg(n);
  for (i64 i = 0; i < n; i++) {
    seg.set(i, {a[i], i});
  }
  vector<vector<i64>> pars(n);
  vector<i64> ord(n, -1);
  i64 cnt = 0;
  while (seg.all_prod().first == 0) {
    auto [_, i] = seg.all_prod();
    ord[i] = cnt++;
    seg.set(i, e());
    i64 l = seg.min_left(i, [&](p2 t){return t == e();}) - 1;
    i64 r = seg.max_right(i, [&](p2 t){return t == e();});
    if (l >= 0) {
      auto [x, li] = seg.get(l);
      seg.set(l, {x - 1, li});
      pars[i].push_back(l);
    }
    if (r < n) {
      auto [x, ri] = seg.get(r);
      seg.set(r, {x - 1, ri});
      pars[i].push_back(r);
    }
  }
  if (seg.all_prod() != e()) {
    cout << "0\n";
    return;
  }
  vector<i64> par(n, -1);
  for (i64 i = 0; i < n; i++) {
    if (pars[i].empty()) continue;
    if (pars[i].size() == 1) {
      par[i] = pars[i][0];
      continue;
    }
    i64 x = pars[i][0], y = pars[i][1];
    if (ord[x] < ord[y]) par[i] = x;
    else par[i] = y;
  }
  i64 root = -1;
  for (i64 i = 0; i < n; i++) {
    if (par[i] != -1) {
      g[par[i]].push_back(i);
    } else root = i;
  }
  auto [siz, res] = dfs(root);
  assert(siz == n);
  cout << res.val() << "\n";
}
0