Uestc_1546
This question can be used to judge the sequence of legal parentheses and regard '(' as 1, ')' As-1, then scan a sequence from left to right and accumulate the scanned values. In this process, if the sum of these values is not less than 0 at any time, and the sum of these values is 0 at the end, it indicates that the sequence of parentheses is valid.
So we only need to use the line segment tree to modify and query the operation. This problem is solved. To facilitate modification and query, we can use two tags: To and rev. To indicates whether the range is set, and Rev indicates whether the range is flipped. At the same time, we can maintain three values: Lmin, Lmax, and sum. Lmin indicates the minimum prefix and minimum starting from the left endpoint of the current interval, and Lmax indicates the maximum prefix and starting from the current interval, sum indicates the sum of the current range.
# Include <stdio. h> # Include < String . H> # Define Maxd 100010 Int N, m, [ 4 * Maxd], rev [4 * Maxd], Lmin [ 4 * Maxd], Lmax [ 4 * Maxd], sum [ 4 * Maxd]; Char B [maxd]; Void Swap ( Int & X, Int & Y ){ Int T; t = X, x =-y, y =- T ;} Void Pushdown ( Int Cur, Int X, Int Y ){ Int Mid = (x + y)> 1 , Ls = cur < 1 , RS = cur < 1 | 1 ; If (To [cur]! =- 1 ) {To [ls] = To [RS] = To [cur]; rev [ls] = Rev [RS] = 0 ; If (To [cur]) {sum [ls] = Mid-x + 1 , Sum [RS] = y- Mid; Lmin [ls] = Lmin [RS] = 0 ; Lmax [ls] = Mid-x + 1 , Lmax [RS] = y- Mid ;} Else {Sum [ls] =-(Mid-x + 1 ), Sum [RS] =-(Y- Mid); Lmin [ls] =-(Mid-x + 1 ), Lmin [RS] =-(Y- Mid); Lmax [ls] = Lmax [RS] = 0 ;} To [cur] =- 1 ;} If (Rev [cur]) {rev [ls] ^ = 1 , Rev [RS] ^ =1 ; Sum [ls] =-Sum [ls], sum [RS] =- Sum [RS]; swap (Lmin [ls], Lmax [ls]), swap (Lmin [RS], Lmax [RS]); rev [cur] = 0 ;}} Void Update ( Int Cur ){ Int Ls = cur < 1 , RS = cur < 1 | 1 ; Sum [cur] = Sum [ls] +Sum [RS]; Lmin [cur] = Lmin [ls]; If (Sum [ls] + Lmin [RS] < Lmin [cur]) Lmin [cur] = Sum [ls] + Lmin [RS]; Lmax [cur] = Lmax [ls]; If (Sum [ls] + Lmax [RS]> Lmax [cur]) Lmax [cur] = Sum [ls] + Lmax [RS];} Void Build ( Int Cur, Int X,Int Y ){ Int Mid = (x + y)> 1 , Ls = cur < 1 , RS = cur < 1 | 1 ; To [cur] =- 1 , Rev [cur] = 0 ; If (X = Y ){ If (B [x] =' ( ' ) Sum [cur] = Lmax [cur] = 1 , Lmin [cur] = 0 ; Else Sum [cur] = Lmin [cur] =- 1 , Lmax [cur] = 0 ; Return ;} Build (LS, X, mid); Build (RS, mid +1 , Y); Update (cur );} Void Query ( Int Cur, Int X, Int Y, Int S, Int T, Int & Min, Int & SS ){ Int Mid = (x + y)> 1 , Ls = cur <1 , RS = cur < 1 | 1 ; If (X> = S & Y <= T ){ If (SS + Lmin [cur] < Min) min = SS + Lmin [cur]; SS + = Sum [cur]; Return ;} Pushdown (cur, x, y ); If (Mid> =S) query (LS, X, mid, S, T, Min, SS ); If (Mid + 1 <= T) query (RS, mid + 1 , Y, S, T, Min, SS );} Void Refresh ( Int Cur, Int X, Int Y, Int S, Int T, Int C ){ Int Mid = (x + y)> 1 , Ls = cur < 1 , RS = cur < 1 | 1 ; If (X> = S & Y <= T) {to [cur] = C, rev [cur] = 0 ; If (C) sum [cur] = Lmax [cur] = Y-x +1 , Lmin [cur] = 0 ; Else Sum [cur] = Lmin [cur] =-(Y-x + 1 ), Lmax [cur] = 0 ; Return ;} Pushdown (cur, x, y ); If (Mid> = S) Refresh (LS, X, mid, S, T, C ); If (Mid + 1 <= T) Refresh (RS, mid + 1 , Y, S, T, C); Update (cur );} Void Reverse ( Int Cur, Int X, Int Y, Int S, Int T ){ Int Mid = (x + y)> 1 , Ls = cur < 1 , RS = cur < 1 | 1 ; If (X> = S & Y <= T) {rev [cur] ^ = 1 ; Sum [cur] =- Sum [cur], swap (Lmin [cur], Lmax [cur]); Return ;} Pushdown (cur, x, y ); If (Mid> = S) reverse (LS, X, mid, S, T ); If (Mid + 1 <= T) reverse (RS, mid + 1 , Y, S, T); Update (cur );} Void Solve (){ Int I, Q, X, Y, Min, SS; Char Ch [ 10 ]; Scanf ( " % D " ,&Q ); For (I = 0 ; I <q; I ++ ) {Scanf ( " % S % d " , CH, & X ,& Y ); If (CH [ 0 ] = ' S ' ) {Scanf ( " % S " , CH); refresh ( 1 , 0 , N- 1 , X, Y, CH [ 0 ] = ' ( ' ? 1 : 0 );} Else If (CH [0 ] = ' R ' ) Reverse ( 1 , 0 , N- 1 , X, y ); Else {Min = Ss = 0 ; Query ( 1 , 0 , N-1 , X, Y, Min, SS ); If (Ss = 0 & Min = 0 ) Printf ( " Yes \ n " ); Else Printf ( " No \ n " );}}} Void Init () {scanf ( " % D " ,& N); scanf ( " % S " , B); Build ( 1 , 0 , N- 1 );} Int Main (){ Int T, TT; scanf ( " % D " ,& T ); For (Tt = 0 ; TT <t; TT ++ ) {Init (); printf ( " Case % d: \ n " , Tt + 1 ); Solve (); printf ( " \ N " );} Return 0 ;}