結果

問題 No.3004 ヤング図形
ユーザー Mao-beta
提出日時 2025-02-03 14:13:00
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
MLE  
実行時間 -
コード長 2,785 bytes
コンパイル時間 5,340 ms
コンパイル使用メモリ 198,596 KB
実行使用メモリ 816,640 KB
最終ジャッジ日時 2025-02-03 14:13:38
合計ジャッジ時間 34,978 ms
ジャッジサーバーID
(参考情報)
judge4 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 6 MLE * 19
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
// The modulus used in calculations.
const ll MOD = 998244353;
// Returns a % mod in the range [0, mod-1]
inline ll safe_mod(ll a, ll mod = MOD) {
ll res = a % mod;
if (res < 0)
res += mod;
return res;
}
// Safe multiplication modulo mod using __int128 to avoid overflow.
// This function first reduces both factors to the range [0, mod-1].
inline ll mulmod(ll a, ll b, ll mod = MOD) {
a = safe_mod(a, mod);
b = safe_mod(b, mod);
return ( (__int128) a * b ) % mod;
}
// Fast modular exponentiation with safe modulo operations.
ll modPow(ll base, ll exp, ll mod = MOD) {
ll result = 1;
base = safe_mod(base, mod);
while(exp > 0) {
if(exp & 1)
result = mulmod(result, base, mod);
base = mulmod(base, base, mod);
exp >>= 1;
}
return result;
}
// Combination class: precomputes factorials and inverses modulo mod.
struct Comb {
int n;
ll mod;
vector<ll> fac, inv;
// Constructor precomputes factorials and inverses up to n.
Comb(int n, ll mod) : n(n), mod(mod) {
fac.resize(n + 1);
inv.resize(n + 1);
fac[0] = 1;
for (int i = 1; i <= n; i++) {
fac[i] = mulmod(fac[i - 1], i, mod);
}
// Compute the modular inverse of fac[n] using Fermat's little theorem.
inv[n] = modPow(fac[n], mod - 2, mod);
for (int i = n - 1; i >= 0; i--) {
inv[i] = mulmod(inv[i + 1], i + 1, mod);
}
}
// Returns C(n, r) modulo mod.
ll C(int n, int r) {
if(r < 0 || r > n) return 0;
return mulmod(mulmod(fac[n], inv[r], mod), inv[n - r], mod);
}
};
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int K;
cin >> K;
vector<pair<int, int>> LM(K);
ll total = 0;
for (int i = 0; i < K; i++){
int l, m;
cin >> l >> m;
LM[i] = {l, m};
total += (ll)l * m;
}
int N = (int) total;
// Initialize the combination object with N+1.
Comb comb(N + 1, MOD);
ll ans = 1;
// Process the groups in reverse order (mirroring Python's LM[::-1]).
for (int i = K - 1; i >= 0; i--){
int l = LM[i].first;
int m = LM[i].second;
int lm = l * m; // Total items in this group.
// tmp starts as C(N, l*m)
ll tmp = comb.C(N, lm);
// For each occurrence in this group, multiply by C(lm-1, l-1)
for (int j = 0; j < m; j++){
tmp = mulmod(tmp, comb.C(lm - 1, l - 1), MOD);
lm -= l;
N -= l;
}
ans = mulmod(ans, tmp, MOD);
}
// Print the final answer.
cout << ans << "\n";
return 0;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0