Problem:
Parentheses Editor
You are working with a strange text editor for texts consisting only of open and close parentheses. The editor accepts the following three keys as editing commands to modify the text kept in it.
‘
(
’ appends an open parenthesis (‘
(
’) to the end of the text.
‘
)
’ appends a close parenthesis (‘
)
’) to the end of the text.
‘
-
’ removes the last character of the text.
A balanced string is one of the following.
“
()
”
“
(
$X$
)
” where $X$ is a balanced string
“$XY$” where both $X$ and $Y$ are balanced strings
Initially, the editor keeps an empty text. You are interested in the number of balanced substrings in the text kept in the editor after each of your key command inputs. Note that, for the same balanced substring occurring twice or more, their occurrences should be counted separately.  Also note that, when some balanced substrings are inside a balanced substring, both the inner and outer balanced substrings should be counted.
Input
The input consists of a single test case given in a line containing a number of characters, each of which is a command key to the editor, that is, either ‘
(
’, ‘
)
’, or ‘
-
’. The number of characters does not exceed 200 000. They represent a key input sequence to the editor.
It is guaranteed that no ‘
-
’ command comes when the text is empty.
Output
Print the numbers of balanced substrings in the text kept in the editor after each of the key command inputs are applied, each in one line. Thus, the number of output lines should be the same as the number of characters in the input line.
Sample Input 1
(()())---)
Sample Output 1
0
0
1
1
3
4
3
1
1
2
Sample Input 2
()--()()----)(()()))
Sample Output 2
0
1
0
0
0
1
1
3
1
1
0
0
0
0
0
1
1
3
4
4

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for(ll i = 0; i < n; ++i)
#define vl vector<ll>
#define vvl vector<vvl>

int main(){
    string s;
	cin>>s;
	
	vl ansst={0};
	vl sums{0};
	map<ll,vl> mp;
	mp[0].push_back(0);

	rep(i,s.size()){
		if(s[i]=='('){
			ansst.push_back(ansst.back());
			sums.push_back(sums.back()+1);
			mp[sums.back()].push_back(sums.size()-1);
		}
		if(s[i]==')'){
			//累積和に追加
			sums.push_back(sums.back()-1);
			
			//1小さい奴のindex
			ll mind ;
			if(mp[sums.back()-1].size()==0)mind=0;
			else mind=mp[sums.back()-1].back();

			ll plus=mp[sums.back()].end()-lower_bound(mp[sums.back()].begin(),mp[sums.back()].end(),mind);
			ansst.push_back(ansst.back()+plus);

			//mapを更新
			mp[sums.back()].push_back(sums.size()-1);
		}
		if(s[i]=='-'){
			ansst.pop_back();
			mp[sums.back()].pop_back();
			sums.pop_back();
		}
		cout<<ansst.back()<<endl;
	}
}
accuracy: 1
time_ms: 240
memory_kb: 28204
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define pll pair<LL,LL>
#define x first
#define y second
#define pi acos(-1)
#define sqr(x) ((x)*(x))
#define pdd pair<double,double>
#define MEMS(x) memset(x,-1,sizeof(x))
#define MEM(x) memset(x,0,sizeof(x))
#define less Less
#define EPS 1e-4
#define arg ARG
#define cpdd const pdd
#define rank Rank
#define KK 500
#define N 100005
#define MXN 2000005
const int mod=1e6+3;
int main(){
    int cnt=0;
    LL ans=0;
    vector<pii> v;
    vector<char> vv;
    vector<pii> remove;
    v.pb(mp(0,0));
    cnt=1;
    char c[200005];
    scanf("%s",c);
    for(int i = 0;c[i]!=0;i++){
        if(c[i]=='('){
            vv.pb('(');
            v.pb(mp(v.back().x+1,0));
        }
        else if(c[i]==')'){
            vv.pb(')');
            if(v.back().x==0){
                v.pb(mp(0,0));
            }
            else{
                remove.pb(v.back());
                v.pop_back();
                
                v.back().y++;
                ans+=v.back().y;
            }
        }
        else{
            if(vv.back()=='('){
                vv.pop_back();
                v.pop_back();
            }
            else{
                vv.pop_back();
                if(v.back()==mp(0,0)){
                    v.pop_back();
                }
                else{
                    ans-=v.back().y;
                    v.back().y--;
                    v.pb(remove.back());
                    remove.pop_back();
                }
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 6156
final_rank: 2

code_snippet: #include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
using namespace std;
 
typedef long long LL;
 
typedef unsigned long long ull;
 
const int inf=0x3f3f3f3f;

const int N=1e6+100;

stack<int>st1,st2;

stack<char>st;

char s[N];
 
int main()
{
#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);
	scanf("%s",s+1);
	int n=strlen(s+1);
	int ans=0;
	st1.push(0);
	for(int i=1;i<=n;i++)
	{
		if(s[i]=='(')
		{
			st1.push(0);
			st.push(s[i]);
		}
		else if(s[i]==')')
		{
			if(st1.size()==1)
			{
				st2.push(st1.top());
				st1.top()=0;
				st.push('*');
			}
			else
			{
				st2.push(st1.top());
				st1.pop();
				st1.top()++;
				ans+=st1.top();
				st.push(s[i]);
			}
		}
		else
		{
			if(st.top()=='(')
			{
				st1.pop();
			}
			else if(st.top()=='*')
			{
				st1.top()=st2.top();
				st2.pop();
			}
			else
			{
				ans-=st1.top();
				st1.top()--;
				st1.push(st2.top());
				st2.pop();
			}
			st.pop();
		}
		printf("%d\n",ans);
	}













	return 0;
}
accuracy: 0.45614035087719296
time_ms: 10
memory_kb: 4140
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=(int)2e5+7;
priority_queue<int>Q;
char str[maxn];
int dp[maxn];
int num[maxn];
int pos;
int vis[maxn];
char nows[maxn];
int main()
{
    scanf("%s",str+1);
    pos=0;
    for(int i=1;str[i];i++){
        if(str[i]!='-')pos++;

        //cout<<i<<" "<<str[i]<<" "<<lpi<<endl;
        if(str[i]=='('){
            dp[pos]=dp[pos-1];
            //lp[++lpi]=pos;
            Q.push(pos);
            nows[pos]='(';

        }
        else if(str[i]==')'){
            nows[pos]=')';
            if(Q.empty()){
                dp[pos]=dp[pos-1];
                num[pos]=0;
                //pos++;

            }
            else {
                dp[pos]=dp[pos-1]-dp[Q.top()]+1+dp[Q.top()-1]+num[Q.top()-1];
                num[pos]=num[Q.top()-1]+1;
                vis[pos]=Q.top();
                //cout<<i<<" "<<dp[pos]<<" "<<num[pos]<<endl;
                //pos++;
                //lpi--;
                Q.pop();
            }

        }
        else {
            if(nows[pos]==')'&&vis[pos]){
                Q.push(vis[pos]);
                //lp[++lpi]=vis[pos];
            }
            dp[pos]=num[pos]=vis[pos]=0;
            pos--;
            while((!Q.empty())&&Q.top()>pos)Q.pop();
        }
        //cout<<i<<" "<<pos<<" "<<dp[pos]<<" "<<num[pos]<<" "<<vis[pos]<<endl;
        printf("%d\n",dp[pos]);
    }
    return 0;
}
accuracy: 0.45614035087719296
time_ms: 10
memory_kb: 6280
final_rank: 19

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
struct node{
	int c,ans,p;
}a[N];
char s[N];
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>(s+1);
	int n=strlen(s+1);
	stack<int>q,l;
	q.push(0);
	for(int i=1;i<=n;i++){
		if(s[i]=='('){
			l.push(i);
			a[i].ans=a[i-1].ans;
			if(s[i-1]==')'){
				a[i].c=a[i-1].c;
			}
		}
		if(s[i]==')'){
			a[i].ans=a[i-1].ans;
			if(!l.empty()){
				a[i].c=a[l.top()].c;
				a[i].c++;
				a[i].ans+=a[i].c;
				a[i].p=l.top();
				l.pop();
			}
		}
		if(s[i]=='-'){
			if(!l.empty()&&q.top()==l.top()){
				l.pop();
			}
			if(a[q.top()].p){
				l.push(a[q.top()].p);
			}
			q.pop();
			a[i]=a[q.top()];
			s[i]=s[q.top()];
		}else{
			q.push(i);
		}
		cout<<a[i].ans<<"\n";
	}
	return 0;
}
accuracy: 0.45614035087719296
time_ms: 10
memory_kb: 6500
final_rank: 20

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+10;
stack<int> st;
char s[N];
int dp[N],mtch[N];//dp[i]:以第i个字符结尾的平衡字符串的数量。
signed main(){
    ios::sync_with_stdio(0);
    cin>>s+1;
    int n=strlen(s+1),cnt=0,ans=0;
    for(int i=1;i<=n;i++){
        if(s[i]=='('){
            cnt++;
            dp[cnt]=0,mtch[cnt]=0;
            st.push(cnt);
        }else if(s[i]==')'){
            cnt++;
            if(!st.empty())mtch[cnt]=st.top(),dp[cnt]=dp[st.top()-1]+1,st.pop();
            else mtch[cnt]=0,dp[cnt]=0;
            ans+=dp[cnt];
        }else if(s[i]=='-'){
            ans-=dp[cnt];
            while(!st.empty()&&st.top()>=cnt)st.pop();
            if(mtch[cnt]!=0)st.push(mtch[cnt]);
            cnt--;
        }
        cout<<ans<<"\n";
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 8020
final_rank: 3

code_snippet: // Yokohama 2019 H Parentheses Editor
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
using LL = long long;
int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  string s;
  cin >> s;
  LL ans = 0, N = s.size(), id = 0;  // id 为当前为第 i 个括号，
  vector<int> D(N + 1), M(N + 1), st;  // D[i] 为以第i个括号结尾的连续平衡串数
  for (char c : s) {  // M[id]:  ')' 已匹配到的左括号的下标。
    if (c == '(') {
      st.push_back(++id), D[id] = 0, M[id] = 0;
    } else if (c == ')') {
      id++;  // D[id] = D[st.top()-1]+1,所有的后缀都延长了1个，还新加了一个
      if (!st.empty())  // 栈非空，可以匹配
        M[id] = st.back(), ans += (D[id] = D[M[id] - 1] + 1), st.pop_back();
      else  // 栈空说明不匹配，说明没有任何匹配
        M[id] = 0, D[id] = 0;
    } else if (c == '-') {
      ans -= D[id];  // 减去id所对应的新增后缀
      if (!st.empty() and st.back() >= id) st.pop_back();
      // while (!st.empty() && st.back() >= id) st.pop_back();  // ?
      if (M[id]) st.push_back(M[id]);  // id和`(`匹配，之前`(`已经弹出，需要还原
      id--;                            // 删除字符
    }
    printf("%lld\n", ans);
  }
  return 0;
}
// AC 100
accuracy: 1
time_ms: 10
memory_kb: 5692
final_rank: 1

code_snippet: #include <bits/stdc++.h>
std::string S;
void solve() {
    std::vector<std::vector<std::vector<int>>> g(1);
    std::vector<std::vector<int>> ch(1), par(1);
    g[0] = std::vector<std::vector<int>>(1);
    ch[0] = par[0] = std::vector<int>(1);
    long long ans = 0;
    int id = 0, cur = 0;
    std::string T;
    for (char c : S) {
        //std::cout << c << "!" << std::endl;
        if (c == '(') {
            g[id][cur].push_back(ch[id].size());
            g[id].push_back(std::vector<int>{});
            ch[id].push_back(0);
            par[id].push_back(cur);
            ch[id][cur]++;
            cur = ch[id].size() - 1;
            T += '(';
        }
        else if (c == ')') {
            if (cur == 0) {
                g.push_back(std::vector<std::vector<int>>(1));
                ch.push_back(std::vector<int>(1));
                par.push_back(std::vector<int>(1));
                id++;
                cur = 0;
            }
            else {
                ans += ch[id][par[id][cur]];
                cur = par[id][cur];
            }
            T += ')';
        }
        else if (c == '-') {
            if (T.back() == '(') {
                T.pop_back();
                cur = par[id][cur];
                ch[id][cur]--;
                par[id].pop_back();
                ch[id].pop_back();
                g[id][cur].pop_back();
            }
            else if (T.back() == ')') {
                T.pop_back();
                if (g[id][cur].empty()) {
                    assert(ch[id].size() == 1u); 
                    assert(cur == 0);
                    id--;
                    par.pop_back();
                    ch.pop_back();
                    g.pop_back();
                }
                else {
                    cur = g[id][cur].back();
                    ans -= ch[id][par[id][cur]];
                }
            }
            else {
                assert(!"empty -");
            }
        }
        else {
            assert(false);
        }
        std::cout << ans << '\n';
    }
}
int main() {
    std::cin >> S;
    solve();
}
accuracy: 1
time_ms: 30
memory_kb: 39448
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep2(i, n) for (ll i = 0; i < (n); i++)
#define rep3(i, a, b) for (ll i = a; i < (b); i++)
#define overload(a, b, c, d, ...) d
#define rep(...) overload(__VA_ARGS__, rep3, rep2)(__VA_ARGS__)
#define all(a) begin(a), end(a)
#define sz(a) ssize(a)
bool chmin(auto& a, auto b) { return a > b ? a = b, 1 : 0; }
bool chmax(auto& a, auto b) { return a < b ? a = b, 1 : 0; }

struct Node;
using NodePtr = Node*;

struct Node {
    ll ans = 0;
    NodePtr parent = nullptr;
    NodePtr left = nullptr;
    NodePtr right = nullptr;
};

NodePtr make_trie(string s) {
    NodePtr root = new Node();
    NodePtr cur = root;
    for (auto c: s) {
        if (c == '(') {
            if (!cur->left) {
                cur->left = new Node();
                cur->left->parent = cur;
            }
            cur = cur->left;
        } else if (c == ')') {
            if (!cur->right) {
                cur->right = new Node();
                cur->right->parent = cur;
            }
            cur = cur->right;
        } else {
            assert(cur->parent);
            cur = cur->parent;
        }
    }

    vector<NodePtr> st;
    auto dfs = [&](auto&& self, NodePtr cur) -> void {
        assert(cur);
        if (cur->left) {
            NodePtr nxt = cur->left;
            nxt->ans = 0;
            st.push_back(cur);
            self(self, nxt);
            assert(st.back() == cur);
            st.pop_back();
        }
        if (cur->right) {
            NodePtr nxt = cur->right;
            if (!st.empty()) {
                NodePtr temp = st.back();
                st.pop_back();
                nxt->ans = temp->ans + 1;
                self(self, nxt);
                st.push_back(temp);
            } else {
                nxt->ans = 0;
                self(self, nxt);
            }
        }
    };

    dfs(dfs, root);
    return root;
}

int main() {
    cin.tie(0)->sync_with_stdio(0);
    string s;
    cin >> s;

    auto trie = make_trie(s);
    ll ans = 0;

    NodePtr cur = trie;
    vector<NodePtr> st;
    for (auto c: s) {
        if (c == '(') {
            assert(cur->left != nullptr);
            cur = cur->left;
            ans += cur->ans;
        } else if (c == ')') {
            assert(cur->right != nullptr);
            cur = cur->right;
            ans += cur->ans;
        } else {
            assert(cur->parent != nullptr);
            ans -= cur->ans;
            cur = cur->parent;
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 10
memory_kb: 30860
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
using i64 = long long;
#define endl '\n'
#define var auto
template<typename T>
struct SegmentTree {
  using F=function<T(T,T)>;int n;F f;T ti;vector<T>dat;
  SegmentTree(){}
  SegmentTree(F f, T ti):f(f),ti(ti){}
  void init(int num) {
    n=1;
    while(n<num)
      n<<=1;dat.assign(n<<1,ti);
  }
  void build(const vector<T>&v) {
    int num=v.size();init(num);
    for(int i=0;i<num;++i)
      dat[n+i]=v[i];
    for(int i=n-1;i;i--)
      dat[i]=f(dat[(i<<1)|0],dat[(i<<1)|1]);
  }
  void set_val(int k,T x) {
    dat[k+=n]=x;
    while(k>>=1)
      dat[k]=f(dat[(k<<1)|0],dat[(k<<1)|1]);
  }
  T query(int a,int b) {
    if(a>=b)
      return ti;T vl=ti,vr=ti;
    for(int l=a+n,r=b+n;l<r;l>>=1,r>>=1) {
      if(l&1)vl=f(vl,dat[l++]);
      if(r&1)vr=f(dat[--r],vr);
    }
    return f(vl,vr);
  }
  template<typename C>
  int find(int st,C&check,T&acc,int k,int l,int r) {
    if(l+1==r) {
      acc=f(acc,dat[k]);return check(acc)?k-n:-1;
    }
    int m=(l+r)>>1;
    if(m<=st)
      return find(st,check,acc,(k<<1)|1,m,r);
    if(st<=l&&!check(f(acc,dat[k]))){
      acc=f(acc,dat[k]);return-1;
    }
    int vl=find(st,check,acc,(k<<1)|0,l,m);
    if(~vl)return vl;
    return find(st,check,acc,(k<<1)|1,m,r);
  }
  template<typename C>
  int find(int st,C&check){
    T acc=ti;return find(st,check,acc,1,0,n);
  }
};

int main() {
  cin.tie(0)->sync_with_stdio(false);
  string s;
  cin >> s;
  ll ans = 0;
  int n = s.length();
  int m = 400000;
  vector<vector<int>> ilist(2 * m);
  for (int i = 0; i < 2 * m; i++) {
    ilist[i].push_back(-1);
  }
  SegmentTree<int> lasti([&](int a, int b) { return max(a, b); }, -1);
  vector<int> lastiinit(2 * m, -1);
  vector<int> c(n);
  vector<int> anss{0};
  lasti.build(lastiinit);
  vector<int> cur;
  int depth = m;
  int cl = 0;
  for (int i = 0; i < n; i++) {
    c[cl] = ilist[depth].size();
    if (s[i] != '-') {
      lasti.set_val(depth, cl);
      ilist[depth].push_back(cl);
      if (s[i] == '(') {
        cur.push_back(1);
        depth++;
      } else if (s[i] == ')') {
        cur.push_back(-1);
        int l = lasti.query(0, depth - 1);
        // cout << l << " " << cl << " " << i << " " << depth << endl;
        // cout << flush;
        ans += ilist[depth - 1].size() - c[l+1];
        depth--;
      }
      anss.push_back(ans);
      cl++;
    }
    if (s[i] == '-') {
      int lst = cur.back();
      cur.pop_back();
      depth -= lst;
      ilist[depth].pop_back();
      lasti.set_val(depth, ilist[depth].back());
      anss.pop_back();
      ans = anss.back();
      cl--;
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 60
memory_kb: 62336
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

/*
	考察
	(,-のときは特に何もしない
	)のとき、対応する(の位置を探す（ない時は何もしない）
	対応する（があり、新たに括弧列Xが生まれるとする。
	Xのすぐ左隣に別の括弧列YがあるときはX,YXが誕生するので、これを答えに加える。
	Yは複数ある可能性があるのでdp[i]としてその個数を記録しておく。
	ex)
		() ((())) の後ろにXとして()が加わる場合、Yとして数えられるのは
		()と()((()))の2通り
*/

int main(){
	string S; cin >> S;
	int N = S.size();

	vector<ll> dp(N), dp2(N);
	//dp[i] := S[i]=) で終わる括弧列の個数
	//dp2[i] := S[i] で終わる時の答え
	//Find[i] := S[i]=) に対応する開きカッコの位置

	vector<int> stk;

	vector<int> memo(N, -2);
	auto Find = [&](auto&& Find, int pos){
		if(pos <= -1) return -1;
		if(memo[pos] != -2) return memo[pos];
		int ppos = pos;

		while(true){
			int kouho = pos-1;
			if(kouho < 0) return memo[ppos] = -1;
			if(stk[kouho] == 1) return memo[ppos] = kouho;
			pos = Find(Find, kouho);
		}
	};

	for(int t = 0; t < N; t++){
		int pos = stk.size();
		char c = S[t];

		if(c == '('){
			dp2[pos] = pos-1>=0 ? dp2[pos-1] : 0;
			dp[pos] = 0;
			memo[pos] = -2;
			cout << dp2[pos] << '\n';
			stk.push_back(1);
		}

		else if(c == ')'){
			if(pos >= 1){
				memo[pos] = -2;
				int open = Find(Find, pos);

				if(open == -1) dp[pos] = 0;
				else if(open>0 && stk[open-1] == -1) dp[pos] = dp[open-1]+1;
				else dp[pos] = 1;

				dp2[pos] = dp2[pos-1] + dp[pos];
			}
			else{
				dp[pos] = 0;
				dp2[pos] = 0;
				memo[pos] = -1;
			}

			cout << dp2[pos] << '\n';
			stk.push_back(-1);
		}
		else{
			cout << dp2[max(0, pos-2)] << '\n';
			stk.pop_back();
		}
	}
}
accuracy: 1
time_ms: 50
memory_kb: 8276
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

void debug(vector<int> a){
	for(int b: a){
		cout << (b==1 ? '(' : ')');
	}
	cout << endl;
}

int main(){
	string S; cin >> S;
	int N = S.size();

	vector<ll> dp(N), dp2(N);
	//dp[i] := S[i]=) で終わる括弧列の個数
	//dp2[i] := S[i] で終わる時の答え
	//left[i] := S[i]=) に対応する開きカッコの位置

	vector<int> stk;

	vector<int> memo(N, -2);
	auto Find = [&](auto&& Find, int pos){
		if(pos <= -1) return -1;
		if(memo[pos] != -2) return memo[pos];
		int ppos = pos;

		while(true){
			int kouho = pos-1;
			if(kouho < 0) return memo[ppos] = -1;
			if(stk[kouho] == 1) return memo[ppos] = kouho;
			pos = Find(Find, kouho);
		}
	};

	for(int t = 0; t < N; t++){
		int pos = stk.size();
		char c = S[t];

		if(c == '('){
			dp2[pos] = pos-1>=0 ? dp2[pos-1] : 0;
			dp[pos] = 0;
			memo[pos] = -2;
			cout << dp2[pos] << '\n';
			stk.push_back(1);
		}

		else if(c == ')'){
			if(pos >= 1){
				memo[pos] = -2;
				int open = Find(Find, pos);

				if(open == -1) dp[pos] = 0;
				else if(open>0 && stk[open-1] == -1) dp[pos] = dp[open-1]+1;
				else dp[pos] = 1;

				dp2[pos] = dp2[pos-1] + dp[pos];
			}
			else{
				dp[pos] = 0;
				dp2[pos] = 0;
				memo[pos] = -1;
			}

			cout << dp2[pos] << '\n';
			stk.push_back(-1);
		}
		else{
			cout << dp2[max(0, pos-2)] << '\n';
			stk.pop_back();
		}
		//debug(stk); cout << endl;
	}
}
accuracy: 1
time_ms: 50
memory_kb: 8276
final_rank: 5

code_snippet: #include <bits/stdc++.h>
#define ALL(x) x.begin(), x.end()
using ll = long long;
using ld = long double;
using namespace std;
#define dbg(x) cerr << #x << ':' << (x) << endl;

template<class S, S (*op)(S,S), S(*e)()>
struct SegTree {
    int n,size;
    vector<S> d;
    SegTree(int n) : n(n) {
        size = 1;
        while (size < n) size <<= 1;
        d.resize(2*size, e());
    }
    void set(int idx, S val) {
        idx += size;
        d[idx] = val;

        while (idx > 0) {
            idx >>= 1;
            d[idx] = op(d[idx*2], d[idx*2+1]);
        }
    }
    S prod(int l, int r) {
        l += size;
        r += size;
        S sml = e(), smr = e();
        while (l < r) {
            if (l & 1) sml = op(d[l++], sml);
            if (r & 1) smr = op(smr, d[--r]);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }
};

int e() {return -1e9;}

int op(int a, int b) {return max(a, b);}

int main()
{
    string s;
    cin >> s;
    int n = s.size();
    auto calid = [&](int id) -> int {return id + n + 2;};
    vector<vector<int>> id(2 * n + 5);
    for (int i = 0; i < 2 * n + 5; ++i) id[i].push_back(-1e9);
    SegTree<int, op, e> sg(2 * n + 5);
    int sum = 0, len = 0;
    vector<long long> dp(n + 1, -1);
    dp[0] = 0;
    id[calid(0)].push_back(0);
    sg.set(calid(0), 0);
    string nows;
    long long ans = 0;
    for (auto c : s)
    {
        if (c == '-')
        {
            ans -= dp[len];
            dp[len] = -1;
            int sid = calid(sum);
            id[sid].pop_back();
            sg.set(calid(sum), id[sid].back());
            --len;
            sum -= (nows.back() == '(' ? 1 : -1);
            nows.pop_back();
        }
        else
        {
            ++len;
            sum += (c == '(' ? 1 : -1);
            dp[len] = -1;
            int sid = calid(sum), maxid = sg.prod(0, sid);
            dp[len] = dp[maxid < id[sid].back() ? id[sid].back() : len] + 1;
            id[sid].push_back(len);
            ans += dp[len];
            sg.set(sid, len);
            nows.push_back(c);
        }
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 170
memory_kb: 32300
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define ALL(obj) (obj).begin(),(obj).end()

int main(){
	string s;
	cin >> s;
	vector<vector<int>> idx1(2*s.size() + 10);
	vector<vector<int>> idx2(2*s.size() + 10);
	int sum = s.size() + 1;
	vector<int> a(s.size());
	ll ans = 0;
	string t = "";
	for(int i = 0;i < s.size();i++){
		if(s[i] == '('){
			t.push_back('(');
			a[t.size() - 1] = 0;
			sum++;
			idx1[sum].push_back(i);
			idx2[sum].push_back(i);
		}else if(s[i] == ')'){
			t.push_back(')');
			sum--;
			int l = 0;
			if(idx2[sum - 1].size() != 0) l = idx2[sum - 1].back() + 1;
			auto itr = lower_bound(ALL(idx1[sum + 1]),l);
			a[t.size() - 1] = idx1[sum + 1].end() - itr;
			ans += idx1[sum + 1].end() - itr;
			idx2[sum].push_back(i);
		}else{
			if(t.back() == '('){
				idx1[sum].pop_back();
				idx2[sum].pop_back();
				sum--;
			}else{
				ans -= a[t.size() - 1];
				idx2[sum].pop_back();
				sum++;
			}
			t.pop_back();
		}
		cout << ans << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 35456
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define ALL(obj) (obj).begin(),(obj).end()

int main(){
	string s;
	cin >> s;
	vector<vector<int>> idx1(2*s.size() + 1);
	vector<vector<int>> idx2(2*s.size() + 1);
	int sum = s.size();
	vector<int> a(s.size());
	ll ans = 0;
	string t = "";
	for(int i = 0;i < s.size();i++){
		if(s[i] == '('){
			t.push_back('(');
			a[t.size() - 1] = 0;
			sum++;
			idx1[sum].push_back(i);
			idx2[sum].push_back(i);
		}else if(s[i] == ')'){
			t.push_back(')');
			sum--;
			int l = 0;
			if(idx2[sum - 1].size() != 0) l = idx2[sum - 1].back() + 1;
			auto itr = lower_bound(ALL(idx1[sum + 1]),l);
			a[t.size() - 1] = idx1[sum + 1].end() - itr;
			ans += idx1[sum + 1].end() - itr;
			idx2[sum].push_back(i);
		}else{
			if(t.back() == '('){
				idx1[sum].pop_back();
				idx2[sum].pop_back();
				sum--;
			}else{
				ans -= a[t.size() - 1];
				idx2[sum].pop_back();
				sum++;
			}
			t.pop_back();
		}
		cout << ans << endl;
	}
	return 0;
}
accuracy: 0.7543859649122807
time_ms: 150
memory_kb: 35240
final_rank: 17

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

struct Query {
    int Type;
    ll X;
    ll PreANS;
    Query(int a, ll b, ll c) : Type(a), X(b), PreANS(c) {};
};

int main() {
    string S;
    cin >> S;
    int N = S.size();
    vector<int> A(N);
    rep(i,0,N) {
        if(S[i] == '(') A[i] = 1;
        if(S[i] == '-') A[i] = 0;
        if(S[i] == ')') A[i] = -1;
    }
    ll ANS = 0;
    stack<ll> st;
    st.push(0);
    vector<Query> History;
    rep(i,0,N) {
        if (A[i] == 1) {
            History.push_back(Query(0,0,ANS));
            st.push(0);
        }
        if (A[i] == -1) {
            if (st.size() == 1) {
                History.push_back(Query(1,st.top(),ANS));
                st.pop();
                st.push(0);
            }
            else {
                History.push_back(Query(2,st.top(),ANS));
                st.pop();
                st.top()++;
                ANS += st.top();
            }
        }
        if (A[i] == 0) {
            Query Q = History.back();
            History.pop_back();
            ANS = Q.PreANS;
            if (Q.Type == 0) {
                st.pop();
            }
            if (Q.Type == 1) {
                st.pop();
                st.push(Q.X);
            }
            if (Q.Type == 2) {
                st.top()--;
                st.push(Q.X);
            }
        }
        cout << ANS << endl;
    }
}
accuracy: 1
time_ms: 140
memory_kb: 12912
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, m, n) for (auto i = (m); i < (n); i++)
#define rept(i, n) rep(i, 0, n)
#define repr(i, m, n) for (auto i = (m); i-- > (n);)
#define reptr(i, n) repr(i, 0, n)
#define all(x) begin(x), end(x)
#define sz(x) (int)size(x)
using ll = long long;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vll = vector<ll>;
using vc = vector<char>;
using pii = pair<int, int>;

char inp[200'001];
char buf[200'001];
int hist[200'001];
int f[2000001 * 2];

void solve() {
	scanf("%s", inp);
	int i = 0;
	ll now = 0;
	int x = size(f) / 2;
	f[x] = 1;
	for (char *p = inp; *p; p++) {
		if (*p == '(') {
			x++;
			buf[i] = '(';
			assert(f[x] == 0);
			f[x]++;
			i++;
		} else if (*p == ')') {
			x--;
			buf[i] = ')';
			hist[i] = f[x+1];
			now += f[x];
			f[x+1] = 0;
			f[x]++;
			i++;
		} else {
			i--;
			if (buf[i] == '(') {
				f[x]--;
				x--;
			} else {
				f[x]--;
				f[x+1] = hist[i];
				now -= f[x];
				x++;
			}
		}
		printf("%lld\n", now);
	}
}

int main() {
	int n = 1;
	// scanf("%d", &n);
	while (n--) solve();
}
accuracy: 1
time_ms: 10
memory_kb: 10056
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;



int main() {
    string S;
    cin>>S;
    int N=S.size();
    ll an=0;
    vector<vector<int>> B(2*N+3,{-2});
    int F=N+1;
    B[F].push_back(-1);
    stack<char> C;
    for(int i=0;i<N;i++){
        char s=S[i];
        if(s=='-'){
            char c=C.top();
            C.pop();
            B[F].pop_back();
            an-=B[F].end()-upper_bound(B[F].begin(),B[F].end(),B[F-1].back());
            F+=(c==')'?1:-1);
        }
        else{
            C.push(s);
            F+=(s=='('?1:-1);
            an+=B[F].end()-upper_bound(B[F].begin(),B[F].end(),B[F-1].back());
            B[F].push_back(i);
        }
        cout<<an<<endl;
    }   
}
accuracy: 1
time_ms: 160
memory_kb: 26588
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;

template <typename Monoid>
struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;

  int sz;
  vector<Monoid> seg;

  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while (sz < n) sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) { seg[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) L = f(L, seg[a++]);
      if (b & 1) R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const { return seg[k + sz]; }
};

int op(int a, int b) {return min(a, b);}
int INF = 1e9;

const int BASE = 2e5 + 100;

int main() {
  string S; cin >> S;
  int N = S.length();
  
  vector<int> pr;
  vector<vector<int>> high(BASE * 2);
  SegmentTree<int> seg(N+1, op, INF);
  
  ll res = 0;
  int h = BASE, id = 0;
  high[h].emplace_back(id);
  seg.update(id, h);
  id++;
  
  for (int i = 0; i < N; ++i) {
    char c = S[i];
    
    if (c == '-') {
      int p = pr.back();
      pr.pop_back();
      res -= p;
      
      id--;
      int hh = seg[id];
      int d = seg[id] - seg[id - 1];
      
      seg.update(id, INF);
      high[hh].pop_back();
      assert(d == 1 || d == -1);
      if (d > 0) h--;
      else h++;
    }
    else if (c == '(') {
      h++;
      high[h].emplace_back(id);
      seg.update(id, h);
      id++;
      
      // ll ng = -1, ok = high[h].size() - 1;
      // while (abs(ok - ng) > 1) {
      //   ll mid = (ok + ng) / 2;
      //   ll j = high[h][mid];
      //   if (seg.query(mid, id) >= h) ok = mid;
      //   else ng = mid;
      // }
      
      int ans = 0;
      pr.emplace_back(ans);
      res += ans;
    }
    else {
      h--;
      high[h].emplace_back(id);
      seg.update(id, h);
      id++;
      
      // cout << i << endl;
      // for (auto id : high[h]) {
      //   cout << id << " ";
      // }
      // cout << endl;
      
      ll ng = -1, ok = high[h].size() - 1;
      while (abs(ok - ng) > 1) {
        ll mid = (ok + ng) / 2;
        ll j = high[h][mid];
        if (seg.query(j, id) >= h) ok = mid;
        else ng = mid;
      }
      
      int ans = high[h].size() - 1 - ok;
      pr.emplace_back(ans);
      res += ans;
    }
    
    cout << res << '\n';
  }
  
  
  return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 21956
final_rank: 11

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

} // namespace macro

using namespace macro;
#line 1 "cp-library/src/data_structure/segtree.hpp"
template < class monoid > struct segtree {
    using S = typename monoid::set;

    segtree() : segtree(0) {}
    segtree(int n) : segtree(vector< S >(n, monoid::id())) {}
    segtree(int n, S s) : segtree(vector< S >(n, s)) {}
    segtree(const vector< S >& v) : _n(int(v.size())) {
        log = ceil_pow2(_n);
        size = 1 << log;
        d = vector< S >(2 * size, monoid::id());
        for(int i = 0; i < _n; i++) d[size + i] = v[i];
        for(int i = size - 1; i >= 1; i--) update(i);
    }
    // a[i] <- x
    void set(int i, S x) {
        assert(0 <= i && i < _n);
        i += size;
        d[i] = x;
        for(int p = 1; p <= log; p++) update(i >> p);
    }
    // a[i]
    S get(int i) {
        assert(0 <= i && i < _n);
        return d[i + size];
    }
    // [l, r)
    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        S sml = monoid::id(), smr = monoid::id();
        l += size, r += size;
        while(l < r) {
            if(l & 1) sml = monoid::op(sml, d[l++]);
            if(r & 1) smr = monoid::op(d[--r], smr);
            l >>= 1, r >>= 1;
        }
        return monoid::op(sml, smr);
    }
    S all_prod() { return d[1]; }
    template < class func > int max_right(int l, func f) {
        assert(0 <= l && l <= _n);
        assert(f(monoid::id()));
        if(l == _n) return _n;
        l += size;
        S sm = monoid::id();
        do {
            while(l % 2 == 0) l >>= 1;
            if(!f(monoid::op(sm, d[l]))) {
                while(l < size) {
                    l = 2 * l;
                    if(f(monoid::op(sm, d[l]))) {
                        sm = monoid::op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = monoid::op(sm, d[l]);
            l++;
        } while((l & -l) != l);
        return _n;
    }
    template < class func > int min_left(int r, func f) {
        assert(0 <= r && r <= _n);
        assert(f(monoid::id()));
        if(r == 0) return 0;
        r += size;
        S sm = monoid::id();
        do {
            r--;
            while(r > 1 && (r % 2)) r >>= 1;
            if(!f(monoid::op(d[r], sm))) {
                while(r < size) {
                    r = 2 * r + 1;
                    if(f(monoid::op(d[r], sm))) {
                        sm = monoid::op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = monoid::op(d[r], sm);
        } while((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    vector< S > d;
    int ceil_pow2(int n) { int x = 0; while((1U << x) < uint(n)) x++; return x; }
    void update(int k) { d[k] = monoid::op(d[2 * k], d[2 * k + 1]); }
};
#line 3 "cp-library/src/algebra/minmax.hpp"

template < class T > class min_monoid {
  public:
    using set = T;
    static constexpr T op(const T &l, const T &r) { return std::min(l, r); }
    static constexpr T id() { return std::numeric_limits< T >::max(); }
    static constexpr bool comm = true;
};

template < class T > class max_monoid {
  public:
    using set = T;
    static constexpr T op(const T &l, const T &r) { return std::max(l, r); }
    static constexpr T id() { return std::numeric_limits< T >::min(); }
    static constexpr bool comm = true;
};
#line 5 "A.cpp"

int main() {
    string query = in();

    const int n = query.size();
    vector<i64> cnt = {0};
    int o = n;
    vector<vector<int>> pos(n + 1 + n); pos[0 + n].push_back(0);
    segtree<min_monoid<int>> seg(n + 1); seg.set(0, 0);
    int i = 1;
    
    for(char c : query) {
        if(c == '-') {
            i--;
            pos[seg.get(i) + n].pop_back();
            cnt.pop_back();
        } else {
            int v = seg.get(i - 1) + (c == '(' ? +1 : -1);
            seg.set(i, v);

            int l = seg.min_left(i + 1, [&](int x) { return v <= x; });
            int now = (pos[v + n].end() - lower_bound(pos[v + n].begin(), pos[v + n].end(), l));
            cnt.push_back(cnt.back() + now);

            pos[v + n].push_back(i);
            i++;
        }

        print(cnt.back());
    }
}
accuracy: 1
time_ms: 30
memory_kb: 22524
final_rank: 7