bzoj 4936: [Ceoi2016]match

来源:互联网 发布:阿里云解析新网域名 编辑:程序博客网 时间:2024/06/06 01:23

题意:

按照要求构造一个最小字典序的括号序列,对于两两匹配的括号,在给出的串中对应位置的字母也要相同。

题解:

一开始看错题了,写了个ZZ代码
然后就什么也不会了。
只知道判断有没有答案就是弄个栈搞搞。
orz:题解
code:

#include<cstdio>#include<cstdlib>#include<iostream>#include<cstring>#include<map>#include<stack>#include<algorithm>#define LL long longusing namespace std;const LL hash=10037;const LL mod=1000000007;char s[100005];stack<int> S;map<int,int> R[30];LL n,p[100005],L[100005];LL pre[100005];LL ans[100005];void solve(LL l,LL r){    if(l>r) return;    ans[l]=1;    LL x=s[l]-'a'+1,pos=R[x][pre[l-1]];    while(ans[pos]!=-1) pos=L[pos];    R[x][pre[l-1]]=L[pos];    ans[pos]=2;    solve(pos+1,r);solve(l+1,pos-1);}int main(){    scanf("%s",s+1);    n=strlen(s+1);    p[0]=1;for(LL i=1;i<=n;i++) p[i]=p[i-1]*hash%mod;    LL now=0;    for(LL i=1;i<=n;i++)    {        LL c=s[i]-'a'+1;        if(S.empty()||s[S.top()]!=s[i])        {            S.push(i);            now=(now+p[S.size()]*c%mod)%mod;        }        else now=(now-p[S.size()]*c%mod+mod)%mod,S.pop();        pre[i]=now;    }    if(!S.empty()) {printf("-1");return 0;}    for(LL i=1;i<=n;i++)    {        LL c=s[i]-'a'+1;        L[i]=R[c][pre[i]];        R[c][pre[i]]=i;    }    memset(ans,-1,sizeof(ans));    solve(1,n);    for (LL i=1;i<=n;i++)    {        if (ans[i]==1) printf("(");        else printf(")");    }}
原创粉丝点击