Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Problem G:
Flipping Parentheses

A string consisting only of parentheses '(' and ')' is called balanced if it is one of the following.

A string "()" is balanced.

Concatenation of two balanced strings are balanced.

When a string $s$ is balanced, so is the concatenation of three strings "(", $s$, and ")" in this order.

Note that the condition is stronger than merely the numbers of '(' and ')' are equal. For instance, "())(()" is not balanced.

Your task is to keep a string in a balanced state, under a severe condition in which a cosmic ray may flip the direction of parentheses.

You are initially given a balanced string. Each time the direction of a single parenthesis is flipped, your program is notified the position of the changed character in the string. Then, calculate and output the leftmost position that, if the parenthesis there is flipped, the whole string gets back to the balanced state. After the string is balanced by changing the parenthesis indicated by your program, next cosmic ray flips another parenthesis, and the steps are repeated several times.

Input

The input consists of a single test case formatted as follows.

$N$ $Q$

$s$

$q_1$

.

.

.

$q_Q$

The first line consists of two integers $N$ and $Q$ ($2 \leq N \leq 300000$, $1 \leq Q \leq 150000$). The second line is a string $s$ of balanced parentheses with length $N$. Each of the following $Q$ lines is an integer $q_i$ ($1 \leq q_i \leq N$) that indicates that the direction of the $q_i$-th parenthesis is flipped.

Output

For each event $q_i$, output the position of the leftmost parenthesis you need to flip in order to get back to the balanced state.

Note that each input flipping event $q_i$ is applied to the string after the previous flip $q_{i−1}$ and its fix.

Sample Input 1

6 3
((()))
4
3
1

Sample Output 1

2
2
1

Sample Input 2

20 9
()((((()))))()()()()
15
20
13
5
3
10
3
17
18

Sample Output 2

2
20
8
5
3
2
2
3
18

In the first sample, the initial state is "((()))". The 4th parenthesis is flipped and the string becomes "(((())". Then, to keep the balance you should flip the 2nd parenthesis and get "()(())". The next flip of the 3rd parenthesis is applied to the last state and yields "())())". To rebalance it, you have to change the 2nd parenthesis again yielding "(()())".

Solution in C (judge verdict: Time Limit Exceeded)

#include <stdio.h>

#define STSIZE 300001
#define TREESIZE 300001 * 4
#define MAX 300000

#define min(x, y) x < y ? x : y

//遅延評価セグメント木
typedef struct{
  int tree[TREESIZE], lazy[TREESIZE], lazyFlag[TREESIZE];
}segtree_t;

//プロトタイプ宣言
int Power2(int n);
void Make_tree(char st[], int n);
void update(int a, int b, int x, int k, int left, int right);
void lazyEvaluate(int k, int left, int right);
int minimum(int a, int b, int k, int left, int right);
int get_leaf(int pos, int k, int left, int right);
//void Print_tree(int n);
void Flip(char st[], int q, int val);
int Balance(char st[], int n);

int f_open = 0, f_close = 0;  //ひっくり返されたとき1になる
segtree_t segtree;

//nより大きい2の累乗
int Power2(int n){
  int value;
  for(value = 1; value < n; value *= 2)
    ;
  return value;
}

//木の作成
void Make_tree(char st[], int n){
  int sum = 0, i, j;

  for(i = 0; st[i] != '\0'; ++i){
    switch(st[i]){
      case '(':
        sum++;
        segtree.tree[n + i - 1] = sum;
        break;
      case ')':
        sum--;
        segtree.tree[n + i - 1] = sum;
        break;
    }
  }
  for(;i < n; ++i)
    segtree.tree[n + i - 1] = MAX;
  for(i = n - 1, j = n + i - 1; j > 0; j -= 2)
    segtree.tree[(j - 1) / 2] = min(segtree.tree[j], segtree.tree[j - 1]);
}

//値の更新
void update(int a, int b, int x, int k, int left, int right){
  lazyEvaluate(k, left, right);
  if(right <= a || b <= left)
    return;
  if(a <= left && right <= b){
    segtree.lazy[k] += x;
    segtree.lazyFlag[k] = 1;
    lazyEvaluate(k, left, right);
  }
  else{
    update(a, b, x, k * 2 + 1, left, (left + right) / 2);
    update(a, b, x, k * 2 + 2, (left + right) / 2, right);
    segtree.tree[k] = min(segtree.tree[k * 2 + 1], segtree.tree[k * 2 + 2]);
  }
}

//遅延評価
void lazyEvaluate(int k, int left, int right){
  if(segtree.lazyFlag[k]){
    segtree.tree[k] += segtree.lazy[k];
    if(right - left > 1){  //kが葉ではないとき
      segtree.lazy[k * 2 + 1] += segtree.lazy[k];
      segtree.lazy[k * 2 + 2] += segtree.lazy[k];
      segtree.lazyFlag[k * 2 + 1] = segtree.lazyFlag[k * 2 + 2] = 1;
    }
    segtree.lazy[k] = 0;
    segtree.lazyFlag[k] = 0;
  }
}

//半閉区間[a, b)の最小値
int minimum(int a, int b, int k, int left, int right){
  lazyEvaluate(k, left, right);
  if(right <= a || b <= left)
    return MAX;
  if(a <= left && right <= b)
    return segtree.tree[k];
  else{
    int vl = minimum(a, b, k * 2 + 1, left, (left + right) / 2);
    int vr = minimum(a, b, k * 2 + 2, (left + right) / 2, right);
    return min(vl, vr);
  }
}

//葉ノードの値を取得
int get_leaf(int pos, int k, int left, int right){
  lazyEvaluate(k, left, right);
  if(pos == left)
    return segtree.tree[k];
  if(pos < (left + right) / 2)
    return get_leaf(pos, k * 2 + 1, left, (left + right) / 2);
  else
    return get_leaf(pos, k * 2 + 2, (left + right) / 2, right);
}

/*
//木の表示
void Print_tree(int n){
  for(int i = 0; i < 2 * n - 1; i++)
    printf("%d ", segtree.tree[i]);
  printf("\n");
}
*/

//位置qの括弧をひっくり返す
void Flip(char st[], int q, int n){
  switch (st[q-1]) {
    case '(':
      st[q-1] = ')';
      f_open = 1;
      update(q - 1, n, -2, 0, 0, n);
      break;
    case ')':
      st[q-1] = '(';
      f_close = 1;
      update(q - 1, n, 2, 0, 0, n);
      break;
  }
}

//ひっくり返したとき括弧の対応がとれている最も左の位置を返す
int Balance(char st[], int n){
  if(f_open){  //開きが閉じにひっくり返されたとき
    for(int i = 1; st[i - 1] != '\0'; ++i)
      if(st[i - 1] == ')'){  //一番左の閉じを開きにすればよい
        Flip(st, i, n);
        return i;
      }
  }
  else if(f_close){  //閉じが開きにひっくり返されたとき
    for(int i = 0; st[i] != '\0'; ++i){
      if(st[i] == '(' && get_leaf(i, 0, 0, n) >= 2){
        //update(i + 1, n, 0, 0, 0, n);
        //printf("%d\n", minimum(i + 1, n, 0, 0, n));
        if(minimum(i + 1, n, 0, 0, n) > 1){
          Flip(st, i + 1, n);
          return i + 1;
        }
      }
    }
  }
  else
    return -1;
}

int main(){
  char st[STSIZE];
  int p, q, n;
  int val;

  scanf("%d%d", &n, &q);
  val = Power2(n);
  scanf("%s", st);
  Make_tree(st, val);
  //Print_tree(val);
  for(int i = 0; i < 2 * val - 1; ++i)
    segtree.lazy[i] = 0;
  for(int i = 1; i <= q; i++){
    f_open = 0; f_close = 0;
    scanf("%d", &p);
    Flip(st, p, val);
    printf("%d\n", Balance(st, val));
    //Print_tree(val);
  }
  return 0;
}