51nod 1791 合法括号子段
【题解】
我们可以发现每一对可以匹配的左右括号一定是一一对应的,那么我们用一个栈维护即可。如果当前是右括号,栈顶是左括号,那么一定有1的贡献,还要加上之前到达过top-1这个位置多少次,因为现在这一对括号可以和之前的那些组成更长的序列。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define LL long long 5 #define N 2200010 6 #define rg register 7 using namespace std; 8 int n,T,top; 9 LL ans; 10 struct stack{ 11 int num; LL cnt; 12 }st[N]; 13 char s[N]; 14 inline int read(){ 15 int k=0,f=1; char c=getchar(); 16 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 17 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 18 return k*f; 19 } 20 int main(){ 21 T=read(); 22 while(T--){ 23 scanf("%s",s+1); n=strlen(s+1); top=0; ans=0; 24 for(rg int i=0;i<=n;i++) st[i].cnt=0; 25 for(rg int i=1;i<=n;i++){ 26 if(s[i]==')'&&top>0&&st[top].num==0) ans+=(++st[--top].cnt); 27 else st[++top]=(stack){s[i]=='('?0:1,0}; 28 // printf("%d %lld %lld\n",top,st[top].cnt,ans); 29 } 30 printf("%lld\n",ans); 31 } 32 return 0; 33 }