結果

問題 No.3652 Range Bracket Sequence
コンテスト
ユーザー gomaazarasi
提出日時 2026-07-20 00:22:02
言語 PyPy3
(7.3.23 + ACL)
コンパイル:
pypy3 -mpy_compile _filename_
実行:
pypy3 _filename_
結果
AC  
実行時間 946 ms / 2,000 ms
+ 144µs
コード長 4,895 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 247 ms
コンパイル使用メモリ 96,244 KB
実行使用メモリ 218,004 KB
最終ジャッジ日時 2026-08-28 21:07:47
合計ジャッジ時間 36,235 ms
ジャッジサーバーID
(参考情報)
judge2_0 / judge3_0
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 57
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

"""
seg = SegTree(segfunc, ide_ele, lst)
で使用

seg.update(i,x)
i番目の要素をxに変更する

seg.query(l,r)
l以上r未満の値を取得

"""

##### segfunc#####
def segfunc(x, y):
    x1,x2,x3 = x
    y1,y2,y3 = y
    
    z3 = min(x1,y2)
    x1,y2 = x1-z3,y2-z3
    
    z1,z2 = x1+y1,x2+y2
    z3 += x3+y3
    
    return [z1,z2,z3]
#################

##### ide_ele#####
ide_ele = [0,0,0]
#################

class SegTree:
    """
    init(init_val, ide_ele): 配列init_valで初期化 O(N)
    update(k, x): k番目の値をxに更新 O(logN)
    query(l, r): 区間[l, r)をsegfuncしたものを返す O(logN)
    """
    def __init__(self, init_val, segfunc, ide_ele):
        """
        init_val: 配列の初期値
        segfunc: 区間にしたい操作
        ide_ele: 単位元
        n: 要素数
        num: n以上の最小の2のべき乗
        tree: セグメント木(1-index)
        """
        self.n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << len(bin(self.n - 1)[2:])
        self.tree = [ide_ele] * 2 * self.num
        # 配列の値を葉にセット
        for i in range(self.n):
            self.tree[self.num + i] = init_val[i]
        # 構築していく
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])
    
    def update(self, k, x):
        """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k - (k&1)], self.tree[k | 1])
            k >>= 1
    
    def add(self, k, x):
        """
        k番目の値をxに更新
        k: index(0-index)
        x: add value
        """
        k += self.num
        self.tree[k] += x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k - (k&1)], self.tree[k | 1])
            k >>= 1
    
    def query(self, l, r):
        """
        [l, r)のsegfuncしたものを得る
        l: index(0-index)
        r: index(0-index)
        """
        resl = self.ide_ele
        resr = self.ide_ele

        l += self.num
        r += self.num
        
        while l < r:
            if l & 1:
                resl = self.segfunc(resl, self.tree[l])
                l += 1
            if r & 1:
                resr = self.segfunc(self.tree[r - 1], resr)
            l >>= 1
            r >>= 1
        
        return self.segfunc(resl, resr)
    
    def mri(self, l, r, func):
      
        if l == 0 and r == self.n:
            if func(self.tree[1]) == False:
                return -1
            index = 1
        
        else:
            index = -1
            
            l += self.num
            r += self.num
            
            while l < r:
                if l & 1:
                    if func(self.tree[l]):
                        index = l
                    l += 1
                if r & 1:
                    if func(self.tree[r - 1]):
                        index = r-1
                        break
                l >>= 1
                r >>= 1
            
            if index == -1:
                return -1
        
        while index < self.num:
            if func(self.tree[index*2 + 1]):
                index <<= 1
                index |= 1
            else:
                index <<= 1
        
        
        return index - self.num
    
    def mli(self, l, r, func):
        
        if l == 0 and r == self.n:
            if func(self.tree[1]) == False:
                return -1
            index = 1
        
        else:
            index = -1
            
            l += self.num
            r += self.num
            
            while l < r:
                if l & 1:
                    if func(self.tree[l]):
                        index = l
                        break
                    l += 1
                if r & 1:
                    if func(self.tree[r - 1]):
                        index = r-1
                l >>= 1
                r >>= 1
            
            if index == -1:
                return -1
        
        while index < self.num:
            
            if func(self.tree[index*2]):
                index <<= 1
            else:
                index <<= 1
                index |= 1
        
        
        return index - self.num

n,q = list(map(int,input().split()))
s = input()
a = []

for i in range(n):
    if s[i] == '(':
        a.append([1,0,0])
    else:
        a.append([0,1,0])

seg = SegTree(a, segfunc, ide_ele)

for i in range(q):
    t,l,r = list(map(int,input().split()))
    l -= 1
    
    if t == 1:
        r -= 1
        a[l][r] = 1
        a[l][r^1] = 0
        seg.update(l,a[l])
    
    elif t == 2:
        print(seg.query(l,r)[2]*2)
0