結果
| 問題 | No.3208 Parse AND OR Affection | 
| コンテスト | |
| ユーザー |  | 
| 提出日時 | 2025-07-22 18:09:36 | 
| 言語 | PyPy3 (7.3.15) | 
| 結果 | 
                                WA
                                 
                             | 
| 実行時間 | - | 
| コード長 | 3,985 bytes | 
| コンパイル時間 | 325 ms | 
| コンパイル使用メモリ | 82,368 KB | 
| 実行使用メモリ | 122,912 KB | 
| 最終ジャッジ日時 | 2025-07-22 18:09:55 | 
| 合計ジャッジ時間 | 16,740 ms | 
| ジャッジサーバーID (参考情報) | judge3 / judge4 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| sample | AC * 1 | 
| other | WA * 20 | 
ソースコード
# Generated By Gemini 2.5 Pro
import sys
# 再帰回数の上限と高速化
sys.setrecursionlimit(252525 + 5)
readline = sys.stdin.readline
# --- グローバル変数 ---
N, Q = 0, 0
A = []  # オペランド (True/False)
H = []  # 変換関数 (0:id, 1:not, 2:const_T, 3:const_F)
NUM_T, TOTAL_T = [], []
SEG_TREE = []
N_prime = 0
# --- 変換関数の定義 ---
# f o g
COMPOSE = [
    [0, 1, 2, 3],  # id o g
    [1, 0, 3, 2],  # not o g
    [2, 2, 2, 2],  # const_T o g
    [3, 3, 3, 3],  # const_F o g
]
# f(T), f(F)
APPLY = [(True, False), (False, True), (True, True), (False, False)]
# --- セグメント木の構築とクエリ ---
def merge(left, right):
    comp_func = COMPOSE[right[0]][left[0]]
    
    # Tから始まる式のTrueの個数
    t_from_t = left[1]
    if APPLY[left[0]][0]: # left.comp(T) == T
        t_from_t += right[1]
    else: # left.comp(T) == F
        t_from_t += right[2]
    # Fから始まる式のTrueの個数
    t_from_f = left[2]
    if APPLY[left[0]][1]: # left.comp(F) == T
        t_from_f += right[1]
    else: # left.comp(F) == F
        t_from_f += right[2]
    return comp_func, t_from_t, t_from_f
def build_seg_tree(k, l, r):
    if r - l == 1:
        func = H[l]
        SEG_TREE[k] = (func, 1 if APPLY[func][0] else 0, 1 if APPLY[func][1] else 0)
        return
    
    mid = (l + r) // 2
    build_seg_tree(2 * k + 1, l, mid)
    build_seg_tree(2 * k + 2, mid, r)
    SEG_TREE[k] = merge(SEG_TREE[2 * k + 1], SEG_TREE[2 * k + 2])
def query_seg_tree(a, b, k, l, r):
    if r <= a or b <= l:
        return (0, 0, 0) # identity, 0, 0
    if a <= l and r <= b:
        return SEG_TREE[k]
    mid = (l + r) // 2
    left_res = query_seg_tree(a, b, 2 * k + 1, l, mid)
    right_res = query_seg_tree(a, b, 2 * k + 2, mid, r)
    return merge(left_res, right_res)
def main():
    global N, Q, A, H, NUM_T, TOTAL_T, SEG_TREE, N_prime
    N, Q = map(int, readline().split())
    X = readline().strip()
    N_prime = (N + 1) // 2
    A = [(X[2 * i] == 'T') for i in range(N_prime)]
    
    op_map = {'+': 0, '*': 1, '^': 2}
    H = [0] * (N_prime - 1)
    for i in range(N_prime - 1):
        op = op_map[X[2 * i + 1]]
        operand = A[i + 1]
        # id, not, const_T, const_F
        if op == 0: H[i] = 2 if operand else 0
        elif op == 1: H[i] = 0 if operand else 3
        else: H[i] = 1 if operand else 0
    NUM_T = [0] * N_prime
    NUM_F = [0] * N_prime
    if A[0]: NUM_T[0] = 1
    else: NUM_F[0] = 1
    for i in range(N_prime - 1):
        h = H[i]
        q = i + 1
        
        t_val, f_val = APPLY[h]
        
        num_t_next = (1 if A[q] else 0)
        if t_val: num_t_next += NUM_T[i]
        if f_val: num_t_next += NUM_F[i]
        NUM_T[q] = num_t_next
        NUM_F[q] = (q + 1) - num_t_next
    TOTAL_T = [0] * (N_prime + 1)
    for i in range(N_prime):
        TOTAL_T[i+1] = TOTAL_T[i] + NUM_T[i]
    SEG_TREE = [(0, 0, 0)] * (4 * (N_prime - 1))
    if N_prime > 1:
        build_seg_tree(0, 0, N_prime - 1)
    for _ in range(Q):
        L, R = map(int, readline().split())
        l_prime, r_prime = (L + 1) // 2, (R + 1) // 2
        
        p_prime = l_prime - 1
        
        # 1. L'以降で始まり、R'以前で終わる式の総数
        ans = TOTAL_T[r_prime] - (TOTAL_T[p_prime] if p_prime > 0 else 0)
        
        # 2. L'より前に始まり、[L', R']の範囲で終わる式の数を引く
        if p_prime > 0:
            num_t_at_p = NUM_T[p_prime - 1]
            num_f_at_p = p_prime - num_t_at_p
            
            # 変換 h_{p'} ... h_{r'-1} を求める
            # この合成結果と途中経過の総数をセグ木で求める
            if p_prime <= r_prime -1:
                _, t_from_t, t_from_f = query_seg_tree(p_prime, r_prime, 0, 0, N_prime - 1)
                correction = num_t_at_p * t_from_t + num_f_at_p * t_from_f
                ans -= correction
        print(ans)
if __name__ == "__main__":
    main()
            
            
            
        