結果
問題 |
No.3138 Minimum Bracket Subsequence
|
ユーザー |
👑 ![]() |
提出日時 | 2025-05-02 18:26:11 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 2,428 bytes |
コンパイル時間 | 2,393 ms |
コンパイル使用メモリ | 193,808 KB |
実行使用メモリ | 17,920 KB |
最終ジャッジ日時 | 2025-05-02 18:26:18 |
合計ジャッジ時間 | 6,576 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 16 TLE * 1 -- * 19 |
ソースコード
#include <bits/stdc++.h> using namespace std; using int64 = long long; const int64 MOD = 998244353; const int MAXK = 500000; // K ≤ 5e5 /* ---------- modular helpers ---------- */ inline int64 mul_mod(int64 a, int64 b) { return (static_cast<__int128>(a) * b) % MOD; } int64 mod_pow(int64 a, unsigned long long e) { int64 r = 1; while (e) { if (e & 1) r = mul_mod(r, a); a = mul_mod(a, a); e >>= 1; } return r; } /* ---------- factorial & inverse ---------- */ int64 fact[MAXK + 1], inv_fact[MAXK + 1]; void init_fact() { fact[0] = 1; for (int i = 1; i <= MAXK; ++i) fact[i] = mul_mod(fact[i - 1], i); inv_fact[MAXK] = mod_pow(fact[MAXK], MOD - 2); for (int i = MAXK; i >= 1; --i) inv_fact[i - 1] = mul_mod(inv_fact[i], i); } /* ---------- C(n,k) (k ≤ 5e5, n ≤ 1e18) ---------- */ int64 nCk_large(unsigned long long n, int k) { if (k < 0 || static_cast<unsigned long long>(k) > n) return 0; k = min<unsigned long long>(k, n - k); int64 res = 1; for (int i = 0; i < k; ++i) { res = mul_mod(res, (n - i) % MOD); } res = mul_mod(res, inv_fact[k]); return res; } /* ---------- main ---------- */ int main() { ios::sync_with_stdio(false); cin.tie(nullptr); unsigned long long N; // up to 1e18 int K; string S; if (!(cin >> N >> K >> S)) return 0; init_fact(); const int half = K / 2; bool hasCloseInFirstHalf = false; for (int i = 0; i < half; ++i) if (S[i] == ')') { hasCloseInFirstHalf = true; break; } int64 ans; if (hasCloseInFirstHalf) { // ---- Case 1 ---- int l = 0; // first ')' in first half while (S[l] != ')') ++l; int r = K - 1; // last '(' anywhere while (S[r] != '(') --r; int d = r - l; // d ≥ 1 unsigned long long n_prime = N - d; // # of slots after squeezing int k_prime = K - d; // ≤ K ≤ 5e5 ans = nCk_large(n_prime, k_prime); // = C(n', k') } else { // ---- Case 2 ---- int64 total = mod_pow(2, N); // all 2^N strings int64 sub = 0; // strings that contain <K chars of S prefix for (int k = 0; k < K; ++k) sub = (sub + nCk_large(N, k)) % MOD; ans = (total - sub + MOD) % MOD; } cout << ans << '\n'; return 0; }