結果

問題 No.3208 Parse AND OR Affection
ユーザー areik
提出日時 2025-07-18 23:19:10
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
WA  
実行時間 -
コード長 4,082 bytes
コンパイル時間 4,484 ms
コンパイル使用メモリ 267,496 KB
実行使用メモリ 17,980 KB
最終ジャッジ日時 2025-07-18 23:19:28
合計ジャッジ時間 17,748 ms
ジャッジサーバーID
(参考情報)
judge5 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 1
other WA * 20
権限があれば一括ダウンロードができます

ソースコード

diff #

#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) {
      array<i64, 2> 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;
        array<i64, 2> 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++;
    array<i64, 2> cnt = {0, 0};
    array<array<i64, 2>, 2> dp1 = {array<i64, 2>{0, 0}, {0, 0}}, cur = {array<i64, 2>{0, 0}, {0, 0}};
    array<i64, 2> dp2 = {0, 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;
        array<array<i64, 2>, 2> ncur = {array<i64, 2>{0, 0}, {0, 0}};
        array<i64, 2> ndp2 = {0, 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;
      array<array<i64, 2>, 2> DP1 = dp1, CUR = cur;
      array<i64, 2> DP2 = dp2, CNT = cnt;
      assert(nl >= l);
      assert((nl - l) % 2 == 0);
      while (nl > l) {
        i64 y = x[nl] == 'T' ? 1 : 0;
        array<array<i64, 2>, 2> ndp1 = {array<i64, 2>{0, 0}, {0, 0}};
        array<array<i64, 2>, 2> ncur = {array<i64, 2>{0, 0}, {0, 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";
  }
}
0