Bracket Sequence Deletion (Codeforces 1657C)
Tags: Greedy, implementation

You are given a bracket sequence consisting of $$$n$$$ characters '(' and/or )'. You perform several operations with it.During one operation, you choose the shortest prefix of this string (some amount of first characters of the string) that is good and remove it from the string.The prefix is considered good if one of the following two conditions is satisfied:  this prefix is a regular bracket sequence;  this prefix is a palindrome of length at least two. A bracket sequence is called regular if it is possible to obtain a correct arithmetic expression by inserting characters '+' and '1' into this sequence. For example, sequences (())(), () and (()(())) are regular, while )(, (() and (()))( are not.The bracket sequence is called palindrome if it reads the same back and forth. For example, the bracket sequences )), (( and )(() are palindromes, while bracket sequences (), )( and ))( are not palindromes.You stop performing the operations when it's not possible to find a good prefix. Your task is to find the number of operations you will perform on the given string and the number of remaining characters in the string.You have to answer $$$t$$$ independent test cases.

Input: The first line of the input contains one integer $$$t$$$ ($$$1 \le t \le 10^4$$$) — the number of test cases. The next $$$2t$$$ lines describe test cases.The first line of the test case contains one integer $$$n$$$ ($$$1 \le n \le 5 \cdot 10^5$$$) — the length of the bracket sequence.The second line of the test case contains $$$n$$$ characters '(' and/or ')' — the bracket sequence itself.It is guaranteed that the sum of $$$n$$$ over all test cases do not exceed $$$5 \cdot 10^5$$$ ($$$\sum n \le 5 \cdot 10^5$$$).

Output: For each test case, print two integers $$$c$$$ and $$$r$$$ — the number of operations you will perform on the given bracket sequence and the number of characters that remain in the string after performing all operations.


Sample Inputs:
5
2
()
3
())
4
((((
5
)((()
6
)((()(

Sample Outputs:
1 0
1 1
2 0
1 0
1 1

Solution (Python):
import sys
input = sys.stdin.readline
print = sys.stdout.write

def solve():
    n = int(input())
    s = input()
    cnt = 0
    l = 0
    while l < n - 1:
        if s[l] == '(' or s[l:l + 2] == '))':
            l += 2
        else:
            r = l + 1
            while r < n and s[r] == '(':
                r += 1
            if r == n:
                break
            l = r + 1
        cnt += 1
    return f'{cnt} {n - l}'
print('\n'.join((solve() for _ in range(int(input())))))

Solution (Python):
for s in [*open(0)][2::2]:
    n = len(s)
    i = c = 1
    while i <= n:
        c += 1
        j = i
        i = i + 2 if ')' > s[i - 1] else s.find(')', i) % n + 2
    print(c - 2, n - j)

Solution (Python):
import sys
import copy
import heapq
import bisect
import functools
from math import *
from collections import defaultdict, Counter, deque
from operator import itemgetter
from itertools import groupby
import itertools
from itertools import accumulate
from decimal import Decimal, ROUND_HALF_UP
readline = lambda : sys.stdin.readline().rstrip()

def solve():
    n = int(readline())
    s = str(readline())
    (cnt, l) = (0, 0)
    while l + 1 < n:
        if s[l] == '(' or (s[l] == ')' and s[l + 1] == ')'):
            l += 2
        else:
            r = l + 1
            while r < n and s[r] != ')':
                r += 1
            if r == n:
                break
            l = r + 1
        cnt += 1
    print(cnt, n - l)

def main():
    t = 1
    t = int(readline())
    for i in range(t):
        solve()
if __name__ == '__main__':
    main()