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. IfS is
valid, (S) is
valid. If U,V are
valid, UV is
valid.
Note:
An empty string is valid. If
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 strings consisting
of '(' or ')' (1≤|s|≤106) .
A string
Output
For each test case, output an integer m=∑i=1|s|(i⋅ansi mod 1000000007) ,
where ansi is
the number of valid substrings which contain i -th
character.
Sample Input
2 ()() ((()))
Sample Output
20 42HintFor the second case,ans={1,2,3,3,2,1} , thenm=1⋅1+2⋅2+3⋅3+4⋅3+5⋅2+6⋅1=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; }
posted on 2017-06-08 10:33 gavanwanggw 阅读(162) 评论(0) 编辑 收藏 举报