[bzoj4936]Match
来源:互联网 发布:网络支付公司 编辑:程序博客网 时间:2024/06/06 14:16
题目大意
给你一个小写字母字符串。
请构造一个合法括号序,使得匹配的括号在原串中字母相同。
要求字典序最小,且要求判断无解。
暴力
我们考虑如何判断无解。
你考虑一个栈,顺序扫这个字符串。
假如当前字符和栈顶字符相同消除栈顶字符,否则将这个字符加进栈中。
这可以得到一个合法解,且我们可以证明任意解可以变成这个合法解。
这就是无解判断。
字典序最小的暴力也很简单。
一些性质
我们设f(l,r)=0/1表示只看l~r是否合法。
我们设s[i]表示将1~i加入栈中后栈内元素情况(用哈希值表示)。
则f(l,r)=1一定要有s[l-1]=s[r]。
我们用过程solve(l,r)表示想要给l~r构造最小字典括号序。
我们需要知道谁和l匹配。
假设为pos。
那么pos=max{x|a[x]=a[l]且f(x+1,r)=1}
然后继续递归solve(pos+1,r)和solve(l+1,pos-1)
如何找到pos成为了问题。
发现f(x+1,r)=1就是s[x]=s[r]。
对于同一哈希值同一字符,它显然是单调的,也就是这个pos在减小。
然后如果我们优先solve(pos+1,r),就可以让所有的指针都到[l,pos],于是继续递归solve(l+1,pos-1)。
然后我们就线性解决了本题。
#include<cstdio>#include<algorithm>#include<cstring>#include<map>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;typedef long long ll;typedef pair<int,int> pi;map<pi,int> p[30];const int maxn=100000+10,mo1=1000000007,mo2=998244353;char s[maxn],ans[maxn];int sta[maxn],left[maxn],mi[maxn][2];pi sum[maxn];int i,j,k,l,t,n,m,tot,top,now1,now2;void solve(int l,int r){ if (l>r) return; ans[l]='('; int pos=p[s[l]-'a'][sum[l-1]]; while (ans[pos]=='('||ans[pos]==')') pos=left[pos]; p[s[l]-'a'][sum[l-1]]=left[pos]; ans[pos]=')'; solve(pos+1,r); solve(l+1,pos-1);}int main(){ freopen("data.in","r",stdin);freopen("wzd.out","w",stdout); scanf("%s",s+1); n=strlen(s+1); mi[0][0]=mi[0][1]=1; fo(i,1,n){ mi[i][0]=(ll)mi[i-1][0]*27%mo1; mi[i][1]=(ll)mi[i-1][1]*27%mo2; } now1=now2=0; sum[0]=make_pair(0,0); fo(i,1,n){ if (top&&s[sta[top]]==s[i]){ (now1-=(ll)(s[sta[top]]-'a'+1)*mi[top-1][0]%mo1)%=mo1; (now1+=mo1)%=mo1; (now2-=(ll)(s[sta[top]]-'a'+1)*mi[top-1][1]%mo2)%=mo2; (now2+=mo2)%=mo2; top--; } else{ (now1+=(ll)(s[i]-'a'+1)*mi[top][0]%mo1)%=mo1; (now2+=(ll)(s[i]-'a'+1)*mi[top][1]%mo2)%=mo2; sta[++top]=i; } sum[i]=make_pair(now1,now2); } if (top){ printf("-1\n"); return 0; } fo(i,1,n){ //if (i){ left[i]=p[s[i]-'a'][sum[i]]; p[s[i]-'a'][sum[i]]=i; //} } solve(1,n); fo(i,1,n) printf("%c",ans[i]);}
阅读全文
0 0
- [bzoj4936]Match
- match
- match
- match
- $match
- Match Point
- javascript:match
- regexp#match
- pattern match
- logic:match
- URL match
- str.match()
- Match Schedule
- patch match
- patch match
- template match
- patch match
- longest match
- 使用Kettle工具通过执行SQL脚本的形式来实现导入到MySQL数据库
- RxLifecycle防内存泄漏分析
- BBB玩机(二)编译环境设置
- Python笔记
- gzip:stdin:not in gzip format
- [bzoj4936]Match
- HDU-1754 I Hate It(线段树求区间最值)
- Android RecyclerView 使用完全解析 体验艺术般的控件
- 【UESTC 982】质因子分解
- POJ 3259 Wormholes spfa
- 笨办法学 Python · 续 练习 51:`lessweb`
- Spring技术内幕——深入解析Spring架构与设计原理(六)Spring ACEGI
- 安卓开发点击退出方法
- 伪终端设备之我见