题解 Bracket

题目描述

题目链接
Tips: 这题求的是最短的字典序最小的括号序列,而不是字典序最小的括号序列,被坑了

题解

前置知识

为了解决本题,你应该要会

  • 括号匹配问题
  • 后缀排序

思路

设原字符串长度为len,不能匹配的左括号数量为l,不能匹配的右括号数量为r
则最终字符串的长度肯定为\(len+|l-r|\)

代码

#include
#include
#include
#include
using namespace std;
int n,rk[2000005],sa[1000005];
int a[2000005],b[2000005],c[2000005],d[2000005],e[2000005];
bool kuo[2000005];
int hao[1000005];
stacks;
vectorg;
void SA(int x) {
	for(int i=0; i<=n; i++)a[i]=b[i]=c[i]=d[i]=e[i]=0;
	for(int i=1; i<=n; i++)a[rk[i]]++,b[rk[i+x]]++;
	for(int i=1; i<=n; i++)a[i]+=a[i-1],b[i]+=b[i-1];
	for(int i=1; i<=n; i++)c[b[rk[i+x]]--]=i;
	for(int i=n; i>=1; i--)d[a[rk[c[i]]]--]=c[i];
	int id=0;
	for(int i=1; i<=n; i++)e[d[i]]=(rk[d[i]]==rk[d[i-1]]&&rk[d[i]+x]==rk[d[i-1]+x]?e[d[i-1]]:++id);
	for(int i=1; i<=n; i++)rk[i]=e[i];
	if(id==n)return;
	SA(x<<1);
}
int main() {
//	freopen("bracket10.in","r",stdin);
//	freopen("test.out","w",stdout);
	char ch;
	while(++n) {
		ch=getchar();
		if(ch==' ')cout<=st)b=(st==0?0:g[st-1]);
	if(st>cnt)en+=(st-cnt);
	while(!s.empty()){
		hao[s.top()]=1;
		if(s.size()==en)fin=s.top();
		s.pop();
	}
	int id=0,l=0,r=0;
	rk[0]=0x3f3f3f3f;
	for(int i=1;i<=b;i++)if(hao[i]==0)kuo[i]?r++:l++;
	for(int i=b+1; i<=fin; i++){
		if(l==r)if(rk[i]

你可能感兴趣的:(题解 Bracket)