問題
2016년의 Distributed Code Jam에서는, 괄호 밀도가 더 높은 것을 선호하는 Lisp 팬들을 위해 Lisp++ 언어를 소개했다. 이 언어의 문법이 어떻게 동작하는지 다시 한 번 상기해 보자:
Lisp++ 프로그램은 균형잡힌 괄호 문자열이다. 좀 더 정확히 말하면, Lisp++ 프로그램은 다음 중 하나로 이루어진다. (이 명세에서 C는 어떤 프로그램 코드 — 매번 같은 코드일 필요는 없음 — 를 의미한다.)
-
()그대로 여는 괄호 하나와 닫는 괄호 하나이다. 이(는 이)와 매칭된다고 하며, 반대도 마찬가지다. -
(C)괄호 한 쌍 안에 들어 있는 하나의 프로그램이다. 이(는 이)와 매칭된다고 하며, 반대도 마찬가지다. - CC 서로 같을 필요가 없는 두 프로그램을 연달아 이어 붙인 것이다.
올해 우리는 Lisp++용 텍스트 뷰어인 Emacs++를 발표하게 되어 기쁘다. Emacs++는 길이가 K인 Lisp++ 프로그램을 한 줄로 길게 표시하고, 그 위에서 커서를 움직일 수 있게 해 준다. 커서는 문자 사이가 아니라 프로그램의 K개 문자 중 하나 위에 항상 놓이는 "블록 커서"다.
어느 시점에서든 커서를 움직이기 위해 다음 세 가지 동작 중 하나를 수행할 수 있다. (i는 커서의 현재 위치이며, 가장 왼쪽이 1이다.)
- 커서를 왼쪽으로 한 글자 이동한다. (커서가 이미 가장 왼쪽 글자 위에 있다면 아무 일도 일어나지 않는다.) 이 동작에는 Li초가 걸린다.
- 커서를 오른쪽으로 한 글자 이동한다. (커서가 이미 가장 오른쪽 글자 위에 있다면 아무 일도 일어나지 않는다.) 이 동작에는 Ri초가 걸린다.
- i번째 글자인 괄호와(위에서 설명한 규칙에 따라) 매칭되는 괄호로 커서를 순간이동(teleport)한다. 이 동작에는 Pi초가 걸린다.
우리는 Emacs++가 파워 유저에게는 단순할 것이라고 생각하지만, 그 효율이 얼마나 되는지 이해할 필요가 있다. Lisp++ 프로그램 하나와 그 프로그램에 대한 Q개의 질의가 주어진다. 각 질의는 시작 위치 Sj와 끝 위치 Ej로 이루어진다. j번째 질의에 답하려면, 최적으로 움직였을 때 커서를 Sj에서 Ej로 옮기는 데 드는 최소 시간 Nj(초)을 구해야 한다.
모든 Nj 값의 합을 출력하라.
輸入
입력의 첫 줄에는 테스트 케이스 수 T가 주어진다. T개의 테스트 케이스가 이어진다. 각 테스트 케이스의 첫 줄에는 두 정수 K와 Q가 주어진다. 이는 Lisp++ 프로그램의 길이와 질의의 개수이다.
테스트 케이스의 둘째 줄에는 길이 K의 문자열 P가 주어진다.
각 문자는 ( 또는 )이며,
위에서 설명한 Lisp++ 프로그램(균형잡힌 괄호 문자열)을 나타낸다.
셋째, 넷째, 다섯째 줄에는 각각 K개의 정수가 주어진다. 이 줄들의 i번째 정수는 각각 위에서 설명한 Li, Ri, Pi이다.
여섯째 줄과 일곱째 줄에는 각각 Q개의 정수가 주어진다. 이 줄들의 j번째 정수는 각각 위에서 설명한 Sj, Ej이다.
輸出
각 테스트 케이스마다 Case #x: y 형식의 한 줄을 출력하라.
여기서 x는 (1부터 시작하는) 테스트 케이스 번호이고,
y는 위에서 설명한 Nj 값들의 합이다.
範例
1
12 5
(()(((()))))
1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1
7 4 4 12 5
12 11 10 1 6
Case #1: 10