結果
問題 | No.1549 [Cherry 2nd Tune] BANning Tuple |
ユーザー |
![]() |
提出日時 | 2021-06-11 22:47:58 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 891 ms / 4,000 ms |
コード長 | 3,241 bytes |
コンパイル時間 | 2,599 ms |
コンパイル使用メモリ | 187,708 KB |
実行使用メモリ | 15,104 KB |
最終ジャッジ日時 | 2024-12-15 01:25:27 |
合計ジャッジ時間 | 17,589 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 20 |
ソースコード
#include <bits/stdc++.h>using namespace std;const long long MOD = 998244353;long long modpow(long long a, long long b){long long ans = 1;while (b > 0){if (b % 2 == 1){ans *= a;ans %= MOD;}a *= a;a %= MOD;b /= 2;}return ans;}long long modinv(long long a){return modpow(a, MOD - 2);}vector<long long> ntt(vector<long long> A, bool inv){int N = A.size();long long r = 3;if (inv){r = modinv(r);}vector<long long> B(N);for (int i = N / 2; i > 0; i /= 2){long long z = modpow(r, (MOD - 1) / (N / i));long long z2 = 1;for (int j = 0; j < N; j += i * 2){for (int k = 0; k < i; k++){A[i + j + k] *= z2;A[i + j + k] %= MOD;B[j / 2 + k] = (A[j + k] + A[i + j + k]) % MOD;B[N / 2 + j / 2 + k] = (A[j + k] - A[i + j + k] + MOD) % MOD;}z2 = z2 * z % MOD;}swap(A, B);}if (inv){int Ninv = modinv(N);for (int i = 0; i < N; i++){A[i] = A[i] * Ninv % MOD;}}return A;}vector<long long> convolution(vector<long long> A, vector<long long> B, int d = -1){int deg = A.size() + B.size() - 1;int N = 1;while (N < deg){N *= 2;}A.resize(N);B.resize(N);A = ntt(A, false);B = ntt(B, false);vector<long long> ans(N);for (int i = 0; i < N; i++){ans[i] = A[i] * B[i] % MOD;}ans = ntt(ans, true);if (d != -1){deg = d;}ans.resize(deg);return ans;}struct segment_tree{int N;vector<vector<long long>> ST;segment_tree(int N2){N = 1;while (N < N2){N *= 2;}ST = vector<vector<long long>>(N * 2 - 1, vector<long long>(3001, 0));for (int i = 0; i < N2; i++){ST[N - 1 + i] = vector<long long>(3001, 1);}for (int i = N2; i < N; i++){ST[N - 1 + i][0] = 1;}for (int i = N - 2; i >= 0; i--){ST[i] = convolution(ST[i * 2 + 1], ST[i * 2 + 2], 3001);}}void update(int i, vector<bool> A){i += N - 1;for (int j = 0; j <= 3000; j++){if (A[j]){ST[i][j] = 1;} else {ST[i][j] = 0;}}while (i > 0){i = (i - 1) / 2;ST[i] = convolution(ST[i * 2 + 1], ST[i * 2 + 2], 3001);}}vector<long long> get(){return ST[0];}};int main(){long long N;int Q;cin >> N >> Q;vector<long long> K(Q);vector<int> A(Q), B(Q), S(Q), T(Q);for (int i = 0; i < Q; i++){cin >> K[i] >> A[i] >> B[i] >> S[i] >> T[i];}vector<long long> K2 = K;sort(K2.begin(), K2.end());K2.erase(unique(K2.begin(), K2.end()), K2.end());for (int i = 0; i < Q; i++){K[i] = lower_bound(K2.begin(), K2.end(), K[i]) - K2.begin();}int cnt = K2.size();long long N2 = N - cnt;vector<long long> dp(3001);dp[0] = 1;for (int i = 0; i < 3000; i++){dp[i + 1] = dp[i] * ((N2 + i) % MOD) % MOD * modinv(i + 1) % MOD;}segment_tree ST(cnt);vector<vector<bool>> ok(cnt, vector<bool>(3001, true));for (int i = 0; i < Q; i++){for (int j = A[i]; j <= B[i]; j++){ok[K[i]][j] = false;}ST.update(K[i], ok[K[i]]);vector<long long> f = ST.get();f = convolution(f, dp, 3001);long long ans = 0;for (int j = S[i]; j <= T[i]; j++){ans += f[j];}ans %= MOD;cout << ans << endl;}}