[bzoj4936]Match
2017-08-16 17:37
218 查看
题目大意
给你一个小写字母字符串。请构造一个合法括号序,使得匹配的括号在原串中字母相同。
要求字典序最小,且要求判断无解。
暴力
我们考虑如何判断无解。你考虑一个栈,顺序扫这个字符串。
假如当前字符和栈顶字符相同消除栈顶字符,否则将这个字符加进栈中。
这可以得到一个合法解,且我们可以证明任意解可以变成这个合法解。
这就是无解判断。
字典序最小的暴力也很简单。
一些性质
我们设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]); }
相关文章推荐
- BZOJ 4936: [Ceoi2016]match
- bzoj 4936: [Ceoi2016]match
- 【BZOJ1264】【AHOI2006】基因匹配Match (dp+树状数组)
- BZOJ 1264 基因匹配Match(LCS转化LIS)
- BZOJ 1264: [AHOI2006]基因匹配Match( LCS )
- 【bzoj2384】[Ceoi2011]Match 特殊匹配条件的KMP+树状数组
- bzoj 1306 [CQOI2009]match循环赛
- bzoj 1306: [CQOI2009]match循环赛【dfs+剪枝】
- bzoj 1306 match循环赛
- bzoj 1264: [AHOI2006]基因匹配Match
- BZOJ1264 [AHOI2006]基因匹配Match
- bzoj 1264 [AHOI2006]基因匹配Match(DP+树状数组)
- BZOJ 1264: [AHOI2006]基因匹配Match|动态规划
- BZOJ [1264] [ AHOI2006]基因匹配Match
- 【BZOJ】【P1306】【CQOI2009】【match循环赛】【题解】【搜索+剪枝】
- [BZOJ1264][AHOI2006]Match(DP+树状数组)
- [bzoj1264][AHOI2006]基因匹配Match 树状数组优化dp
- BZOJ 1264: [AHOI2006]基因匹配Match 树状数组,DP
- 【BZOJ1264】[AHOI2006]基因匹配Match【DP】【LCS】【树状数组】
- [BZOJ1264][AHOI2006]基因匹配Match(DP + 树状数组)