結果
| 問題 |
No.3208 Parse AND OR Affection
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-07-18 23:11:08 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,959 bytes |
| コンパイル時間 | 5,064 ms |
| コンパイル使用メモリ | 273,640 KB |
| 実行使用メモリ | 23,424 KB |
| 最終ジャッジ日時 | 2025-07-18 23:11:35 |
| 合計ジャッジ時間 | 11,958 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| 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 = 300;
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";
}
}