HDU - 5357

本题目的方法,

(()()()) 要处理的大概如图所示,对于任意一个‘(’或者‘)’可以找到其第一个与之匹配的括号,那么记ai为以i为起始位置的所有情况,bi以i为结尾的所有情况,up[I]

为第一个包含(Si->Smatchi)子串的第一个‘(’

那么解为ans[i] = ans[up[i]] +a[i]*a[match[i]];

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define rep1(i,x,y) for(int i=x;i<=y;i++)
#define rep(i,n) for(int i=0;i<(int)n;i++)
const int N= 2000000 + 1000, mod = 1e9 + 7;

int mt[N],up[N],stk[N],n;
LL a[N],b[N],d[N];
char s[N];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
       scanf("%s",s+1); n=strlen(s+1);
       memset(mt,0,sizeof(mt[0])*(n+10));
       memset(up,0,sizeof(up[0])*(n+10));
       memset(a,0,sizeof(a[0])*(n+10));
       memset(b,0,sizeof(a[0])*(n+10));
       memset(d,0,sizeof(d[0])*(n+10));
       int top = 0;
       rep1(i,1,n){
           if(s[i]=='('){
               up[i] = stk[top];
               stk[++top]=i;
           }
           else if(top){
               mt[mt[i]=stk[top--]]=i;
               b[i]=b[mt[i]-1]+1;
           }
       }
       while(top>0) {up[stk[top--]]=0; }
       for(int j=n;j;j--){
           if(s[j]=='(' && mt[j]){
              a[j]=a[mt[j]+1]+1;
           }
       }
       LL ans = 0;
       for(int i=1;i<=n;i++){
          if(s[i] =='(' && mt[i]){
             d[i] = d[mt[i]] = (up[i] ? d[up[i]]:0)+a[i]*b[mt[i]];
          }
          ans+=d[i]*i%mod;
       }
       printf("%I64d\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值