2015 Multi-University Training Contest 6 (hdu 5357 - Easy Sequence)栈的应用
2015-08-11 20:19
381 查看
Easy Sequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 643 Accepted Submission(s): 185
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|≤1061≤|s|≤10^6).
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
42
Hint
For the second case, ans={1,2,3,3,2,1}, then m=1⋅1+2⋅2+3⋅3+4⋅3+5⋅2+6⋅1=42
其覆盖方案分为两种类型:
例子:”…()(…()()()…)()…” (根据合法序列是否覆盖了“包括了它的最小的括号对”进行分类)
合并在一起就求出了每个位置的方案数
做法:计算出第 i 个括号的匹配括号位置 match[i],包含它的括号对的左括号位置 pre[i],以及:
其中,match[i] 和 pre[i] 可以对序列用栈扫一遍求出,具体做法是:遇到左括号压进栈,遇到右括号就弹栈,之前的栈顶元素与当前元素相互 match,现在的栈顶元素成为当前元素及其 match 的 pre。
最后,ans[i] = ans[match[i]] = ans[pre[i]] + forward[i] * backward[match[i]]
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 643 Accepted Submission(s): 185
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|≤1061≤|s|≤10^6).
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
42
Hint
For the second case, ans={1,2,3,3,2,1}, then m=1⋅1+2⋅2+3⋅3+4⋅3+5⋅2+6⋅1=42
其覆盖方案分为两种类型:
例子:”…()(…()()()…)()…” (根据合法序列是否覆盖了“包括了它的最小的括号对”进行分类)
[code]第一部分:倘若它的合法序列覆盖了整个括号对,那么这一部分的方案数等于括号对的总方案数 第二部分:倘若它的合法序列在括号对内,那么这种合法序列一定覆盖了其两边有与其“同级别"(即互不包含)的括号对,设左边有a个,右边有b个,则这一部分的方案数为 (a + 1) * (b + 1)
合并在一起就求出了每个位置的方案数
做法:计算出第 i 个括号的匹配括号位置 match[i],包含它的括号对的左括号位置 pre[i],以及:
[code]对于左括号,其右边的“同级别”的括号个数(包括自己)forward[i] = forward[match[i]+1] + 1 对于右括号,其左边的“同级别”的括号个数(包括自己)backward[i] = backward[match[i]-1] + 1
其中,match[i] 和 pre[i] 可以对序列用栈扫一遍求出,具体做法是:遇到左括号压进栈,遇到右括号就弹栈,之前的栈顶元素与当前元素相互 match,现在的栈顶元素成为当前元素及其 match 的 pre。
最后,ans[i] = ans[match[i]] = ans[pre[i]] + forward[i] * backward[match[i]]
[code]#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> using namespace std; typedef long long LL; const int maxn=1000100; const int maxm=1010; const int MOD=1000000007; const int INF=0x3f3f3f3f; char s[maxn]; int N; int match[maxn],pre[maxn],R[maxn],L[maxn]; LL ans[maxn]; int st[maxn]; void solve(){ for(int i=1;i<=N;i++){ s[i]=(s[i]==')'); } memset(match,0,sizeof(int)*(N+2)); memset(pre,0,sizeof(int)*(N+2)); memset(L,0,sizeof(int)*(N+2)); memset(R,0,sizeof(int)*(N+2)); int top=0; for(int i=1;i<=N;i++){ if(s[i]==0){ st[++top]=i; } else if(top){ match[st[top]]=i; match[i]=st[top]; --top; if(top){ pre[match[i]]=st[top]; } } } for(int i=N;i>0;i--){ if(s[i]==0&&match[i]){ R[i]=R[match[i]+1]+1; } } for(int i=1;i<=N;i++){ if(s[i]==1&&match[i]){ L[i]=L[match[i]-1]+1; } } memset(ans,0,sizeof(LL)*(N+2)); LL res=0; for(int i=1;i<=N;i++){ if(s[i]==0&&match[i]){ ans[i]=ans[match[i]]=(ans[pre[i]]+1LL*R[i]*L[match[i]]%MOD)%MOD; } res+=1LL*i*ans[i]%MOD; } printf("%I64d\n",res); } int main(){ int T; scanf("%d",&T); while(T--){ scanf("%s",s+1); N=strlen(s+1); solve(); } return 0; }
相关文章推荐
- 深入理解urllib、urllib2及requests
- UITableView 隐藏没有数据线条
- Activity里面的UI模板自定义属性,更好的复用TextView,由于在网上没找到类似,记录下来。
- HDU 1242 Rescue
- UITableView
- UGUI Button
- Request Flow for Provisioning Instance in Openstack
- NSURLRequest 获取下载文件的大小(expectedContentLength)
- 带分区的UITableView的创建(省市区字典)
- [iOS]为什么手动打印UITableViewCell的宽度是320高度是44
- [POJ 1679] The Unique MST 最小树
- UI10_tableView的编辑
- Android学习路径(22)应用Fragment建立动态UI——构建一个灵活UI
- UITouch
- UI10_TableView的编辑
- Android API Guides学习2——Common Intents
- UIView中使用了NSNotificationCenter之后,重入时会发生Crash的现象
- CodeForces-450B Jzzhu and Sequences
- 关于UIScrollView事件
- UITableViewCell cell中图片文字的自适应高度