CodeForces - 524F And Yet Another Bracket Sequence

Posted jyyhh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces - 524F And Yet Another Bracket Sequence相关的知识,希望对你有一定的参考价值。

题面在这里!

 

    (会考完之后休闲休闲2333)

    可以发现,如果把一个串中"()"自动删除,最后剩的一定是形如"))))....))(((..((("这样的串,然后我们多加进去的括号的个数就是剩的这个串的长度。。

    然鹅这个题首先要求的是最后总长度最小,并且我们可以观察发现把最后一个循环位移到最前面是会使一对")("相抵消的。

    所以我们最后的最优答案一定是排除已经匹配的括号之后只剩一种括号的串,我们枚举一下循环位移了多少(循环位移之后一定是一个原串的后缀+前缀的形式),然后再判断一下这种循环位移是否会只剩一种串(可以把原串中 ‘(‘个数 - ‘)‘个数 分类讨论一下,然后退出一个形如 一个区间里的前缀/后缀 都要 大于等于 某个前缀/后缀 的式子,可以 O(N) 单调队列扫一遍 ),然后用hash直接更新答案即可,显然最后多的括号都堆在前面或者后面是最优的,然后就做完了2333

 

(最近常数是真的小啊2333)

技术分享图片

 

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2000005,ha=1e9+9;

inline int Get(char x){ return x==‘(‘?1:-1;}

inline int add(int x,int y){ x+=y; return x>=ha?x-ha:x;}

int n,q[maxn],hd,tl,a[maxn],tot,p,N;
int c[maxn],h[maxn];
char s[maxn]; 

inline int gethash(int x,int len){ return add(h[x+len-1],ha-h[x-1]*(ll)c[len]%ha);}

inline bool cmp(int x,int y){
	int l=0,r=n,mid,an=0;
	while(l<=r){
		mid=l+r>>1;
		if(gethash(x,mid)==gethash(y,mid)) an=mid,l=mid+1;
		else r=mid-1;
	}
	
	return an==n?1:s[x+an]==‘(‘;
}

inline void update(int x){ if(!p||cmp(x,p)) p=x;}

inline void solve1(){
	c[0]=1;
	for(int i=1;i<=N;i++){
	    a[i]=a[i-1]+Get(s[i]);
	    c[i]=add(c[i-1],add(c[i-1],c[i-1]));
	    h[i]=add(add(h[i-1],add(h[i-1],h[i-1])),(s[i]==‘(‘?1:2));
	}
	
	hd=1,tl=0;
	for(int i=1;i<N;i++){
		while(hd<=tl&&a[i]<=a[q[tl]]) tl--;
		q[++tl]=i;
		while(hd<=tl&&q[hd]+n<=i) hd++;
		
		if(i>=n&&a[q[hd]]>=a[i-n]) update(i-n+1);
	}
	
	for(int i=0;i<n;i++) putchar(s[p+i]);
	for(int i=1;i<=tot;i++) putchar(‘)‘);
}

inline void solve2(){
	c[0]=1;
	for(int i=1;i<=N;i++){
	    c[i]=add(c[i-1],add(c[i-1],c[i-1]));
	    h[i]=add(add(h[i-1],add(h[i-1],h[i-1])),(s[i]==‘(‘?1:2));
	}
	
	for(int i=N;i;i--) a[i]=a[i+1]-Get(s[i]);
	
	hd=1,tl=0;
	for(int i=N-1;i;i--){
		while(hd<=tl&&a[i]<=a[q[tl]]) tl--;
		q[++tl]=i;
		while(hd<=tl&&q[hd]-n>=i) hd++;
		
		if(i<=n&&a[q[hd]]>=a[i+n]) update(i);
	}
	
	for(int i=tot;i<0;i++) putchar(‘(‘);
	for(int i=0;i<n;i++) putchar(s[p+i]);
}

int main(){
//	freopen("data.in","r",stdin);
//	freopen("data.out","w",stdout);
	
	scanf("%s",s+1),n=strlen(s+1),N=n<<1;
	for(int i=1;i<=n;i++) s[i+n]=s[i],tot+=Get(s[i]);
	
	if(tot>=0) solve1();
	else solve2();
	
	return 0;
}

  

以上是关于CodeForces - 524F And Yet Another Bracket Sequence的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces 621AWet Shark and Odd and Even

codeforces 621A Wet Shark and Odd and Even

CodeForces 621A Wet Shark and Odd and Even

codeforces 621D Rat Kwesh and Cheese

codeforces 621C Wet Shark and Flowers

CodeForces 610D Vika and Segments