HDOJ 5357 Easy Sequence DP


a[i] 表示以i字符开头的合法序列有多少个

b[i] 表示以i字符结尾的合法序列有多少个

up表示上一层的'('的相应位置

mt[i] i匹配的相应位置

c[i] 包括i字符的合法序列个数  c[i]=c[up[i]]+a[i]*b[mt[i]]

括号序列不一定是合法的....

 

Easy Sequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 557    Accepted Submission(s): 165


Problem Description
soda has a string containing only two characters -- '(' and ')'. For every character in the string, soda wants to know the number of valid substrings which contain that character.

Note: 
An empty string is valid. If S is valid, (S) is valid. If U,V are valid, UV is valid.
 

Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

A string s consisting of '(' or ')' (1|s|106).
 

Output
For each test case, output an integer m=i=1|s|(iansi mod 1000000007), where ansi is the number of valid substrings which contain i-th character.
 

Sample Input
2 ()() ((()))
 

Sample Output
20 42
Hint
For the second case, ans={1,2,3,3,2,1}, then m=11+22+33+43+52+61=42
 

Source
 

/* ***********************************************
Author        :CKboss
Created Time  :2015年08月10日 星期一 14时24分51秒
File Name     :HDOJ5357_2.cpp
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;

typedef long long int LL;

const int maxn=1001000;
const LL mod=1e9+7;

int n;
LL a[maxn],b[maxn],mt[maxn];
LL c[maxn];
int up[maxn];
int stk[maxn],top;
char str[maxn];

void init(int n)
{
	top=0;
	memset(mt,0,sizeof(mt[0])*n);
	memset(a,0,sizeof(a[0])*n);
	memset(b,0,sizeof(b[0])*n);
	memset(c,0,sizeof(c[0])*n);
	memset(up,0,sizeof(up[0])*n);
}

int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);

	int T_T;
	scanf("%d",&T_T);
	while(T_T--)
	{
		scanf("%s",str+1);

		n=strlen(str+1);
		init(n+10);

		for(int i=1;i<=n;i++)
		{
			if(str[i]=='(')
			{
				up[i]=stk[top];
				stk[++top]=i;
			}
			else if(top)
			{
				int u=stk[top--];
				mt[u]=i; mt[i]=u;
				b[i]=b[mt[i]-1]+1;
			}
		}

		while(top) mt[stk[top--]]=0;

		for(int i=n;i>=1;i--)
		{
			if(str[i]=='('&&mt[i])
			{
				a[i]=a[mt[i]+1]+1;
			}
		}

		LL ans=0; c[0]=0;
		for(int i=1;i<=n;i++)
		{
			if(str[i]=='('&&mt[i])
			{
				c[mt[i]]=c[i]=c[up[i]]+(LL)a[i]*b[mt[i]];
			}
			ans+=c[i]*i%mod;
		}

		cout<<ans<<endl;
	}
    
    return 0;
}



原文地址:https://www.cnblogs.com/gavanwanggw/p/6961552.html