51nod 1791合法括号子段
有一个括号序列,现在要计算一下它有多少非空子段是合法括号序列。
合法括号序列的定义是:
1.空序列是合法括号序列。
2.如果S是合法括号序列,那么(S)是合法括号序列。
3.如果A和B都是合法括号序列,那么AB是合法括号序列。
Input
多组测试数据。
第一行有一个整数T(1<=T<=1100000),表示测试数据的数量。
接下来T行,每一行都有一个括号序列,是一个由'('和')'组成的非空串。
所有输入的括号序列的总长度不超过1100000。
Output
输出T行,每一行对应一个测试数据的答案。
Input示例
5 ( () ()() (() (())
Output示例
0 1 3 1 2
()是一个合法括号序列,()()是两个合法括号序列。
主要要解决两个合法括号序列组合成新的合法括号序列这个问题。pos[i] 表示第i个右括号与之对应的左括号的位置。ans[i] 表示 在第i个位置一共有多少个。
然后把ans求和就行了。
#include <iostream>
#include <stdio.h>
#include <stack>
#include <string.h>
#define ll long long
using namespace std;
const int N = 1100010;
int t, len;
char str[N];
ll pos[N], ans[N];
int main() {
scanf("%d",&t);
while(t--) {
scanf("%s",str+1);
len = strlen(str+1);
for(int i = 0; i <= len; i ++) {
pos[i] = -1;
ans[i] = 0;
}
stack<int> st;
for(int i = 1; i <= len; i ++) {
if(str[i] == '(') st.push(i);
else {
if(!st.empty()) {
pos[i] = st.top();
st.pop();
}
}
}
ll toc = 0;
for(int i = 1; i <= len; i ++) {
if(pos[i] != -1) {
ans[i] = ans[pos[i]-1]+1;
toc += ans[i];
}
}
cout << toc << endl;
}
return 0;
}

浙公网安备 33010602011771号