結果
問題 |
No.3208 Parse AND OR Affection
|
ユーザー |
![]() |
提出日時 | 2025-07-18 23:10:03 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 3,963 bytes |
コンパイル時間 | 4,708 ms |
コンパイル使用メモリ | 273,012 KB |
実行使用メモリ | 23,892 KB |
最終ジャッジ日時 | 2025-07-18 23:10:26 |
合計ジャッジ時間 | 11,736 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | TLE * 3 -- * 17 |
ソースコード
#include <bits/stdc++.h> #include <atcoder/all> using namespace std; using i32 = int; using i64 = long long; using u64 = unsigned long long; using i128 = __int128_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); _main(); } i64 pow(i64 x, i64 n, i64 m) { i64 res = 1; i64 t = x % m; while (n > 0) { if (n & 1) { res = res * t % m; } t = t * t % m; n >>= 1; } return res; } void _main() { i64 n, q; cin >> n >> q; string x; cin >> x; i64 B = sqrt(q); if (B % 2 != 0) B++; vector<i64> ans(q, 0); vector<p2> query(q); vector<el> ord; vector<vector<p2>> backet(n); for (i64 i = 0; i < q; i++) { i64 l, r; cin >> l >> r; l--; query[i] = {l, r}; if (r - l <= B) { vector<i64> dp = {0, 0}; if (x[l] == 'T') dp[1]++; else dp[0]++; ans[i] += dp[1]; for (i64 j = l + 2; j < r; j += 2) { i64 y = x[j] == 'T' ? 1 : 0; vector<i64> ndp = {0, 0}; ndp[y]++; if (x[j - 1] == '+') { ndp[0 | y] += dp[0]; ndp[1 | y] += dp[1]; } else if (x[j - 1] == '*') { ndp[0 & y] += dp[0]; ndp[1 & y] += dp[1]; } else { ndp[0 ^ y] += dp[0]; ndp[1 ^ y] += dp[1]; } swap(dp, ndp); ans[i] += dp[1]; } continue; } backet[l / B].push_back({r, i}); ord.push_back({l / B, r, i}); } for (i64 b = 0; b < n; b++) { if (backet[b].empty()) continue; i64 L = B * b + B, R = L + 1; if (L % 2 != 0) L++, R++; vector<i64> cnt(2, 0); vector<vector<i64>> dp1(2, vector<i64>(2, 0)), cur(2, vector<i64>(2, 0)); vector<i64> dp2(2, 0); cur[0][0] = cur[1][1] = 1; sort(backet[b].begin(), backet[b].end()); for (auto [_, i] : backet[b]) { auto [l, r] = query[i]; assert(R <= r); assert((r - R) % 2 == 0); while (R < r) { i64 y = x[R + 1] == 'T' ? 1 : 0; vector<vector<i64>> ncur(2, vector<i64>(2, 0)); vector<i64> ndp2(2, 0); for (i64 j = 0; j < 2; j++) { for (i64 k = 0; k < 2; k++) { dp1[j][k] += cur[j][k]; if (x[R] == '+') ncur[j][k ^ y] += cur[j][k]; else if (x[R] == '*') ncur[j][k * y] += cur[j][k]; else ncur[j][k ^ y] += cur[j][k]; } cnt[j] += dp2[j]; if (x[R] == '+') ndp2[j | y] += dp2[j]; else if (x[R] == '*') ndp2[j & y] += dp2[j]; else ndp2[j ^ y] += dp2[j]; } ndp2[y]++; swap(ncur, cur), swap(dp2, ndp2); R += 2; } i64 nl = L; vector<vector<i64>> DP1 = dp1, CUR = cur; vector<i64> DP2 = dp2, CNT = cnt; assert(nl >= l); assert((nl - l) % 2 == 0); while (nl > l) { i64 y = x[nl] == 'T' ? 1 : 0; vector<vector<i64>> ndp1(2, vector<i64>(2, 0)), ncur(2, vector<i64>(2, 0)); for (i64 j = 0; j < 2; j++) { for (i64 k = 0; k < 2; k++) { if (j == y) { CNT[k] += DP1[j][k]; DP2[k] += CUR[j][k]; } if (x[nl - 1] == '+') { ncur[j][k] += CUR[j | y][k]; ndp1[j][k] += DP1[j | y][k]; } else if (x[nl - 1] == '*') { ncur[j][k] += CUR[j & y][k]; ndp1[j][k] += DP1[j & y][k]; } else { ncur[j][k] += CUR[j ^ y][k]; ndp1[j][k] += DP1[j ^ y][k]; } } } ndp1[0][0]++, ndp1[1][1]++; swap(ncur, CUR), swap(DP1, ndp1); nl -= 2; } ans[i] += DP2[1] + CNT[1]; if (x[l] == 'T') { ans[i] += CUR[1][1] + DP1[1][1]; } else { ans[i] += CUR[0][1] + DP1[0][1]; } } } for (i64 i = 0; i < q; i++) { cout << ans[i] << "\n"; } }