結果

問題 No.3208 Parse AND OR Affection
ユーザー areik
提出日時 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
権限があれば一括ダウンロードができます

ソースコード

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 = 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";
  }
}
0