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;
}

  

原文地址:https://www.cnblogs.com/JYYHH/p/9230730.html

时间: 2024-08-06 06:00:43

CodeForces - 524F And Yet Another Bracket Sequence的相关文章

Codeforces 524F And Yet Another Bracket Sequence 哈希

And Yet Another Bracket Sequence 枚举起点, 增加的(肯定在最前面, 增加的)肯定在最后面, 比字典序用hash, 卡了自然溢出.. #include<bits/stdc++.h> #define LL long long #define LD long double #define ull unsigned long long #define fi first #define se second #define mk make_pair #define PLL

【Codeforces 3D】Least Cost Bracket Sequence

Codeforces 3 D 题意:有一个括号序列,其中一些位置是问号,把第\(i\)个问号改成(需要\(a_i\)的代价,把它改成)需要\(b_i\)的代价. 问使得这个括号序列成立所需要的最小代价. 思路1: 这个是正统的贪心. 首先我们假设所有的位置上都是),那么我们在从左向右扫描的途中会发现一些问题. 比如:我们原来的序列是(??),现在假设成了())),那么在第三个字符处就会发现我们的打开的左括号数量为\(-1\),这是肯定不行的,所以我们必须把第二个字符或者第三个字符改成左括号以把左

Codeforces Beta Round #5 C. Longest Regular Bracket Sequence 栈/dp

C. Longest Regular Bracket Sequence Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/problem/5/C Description This is yet another problem dealing with regular bracket sequences. We should remind you that a bracket sequence

贪心+stack Codeforces Beta Round #5 C. Longest Regular Bracket Sequence

题目传送门 1 /* 2 题意:求最长括号匹配的长度和它的个数 3 贪心+stack:用栈存放最近的左括号的位置,若是有右括号匹配,则记录它们的长度,更新最大值,可以在O (n)解决 4 详细解释:http://blog.csdn.net/taoxin52/article/details/26012167 5 */ 6 #include <cstdio> 7 #include <algorithm> 8 #include <cstring> 9 #include <

Codeforces 1132A. Regular Bracket Sequence

原题链接:Codeforces 1132A. Regular Bracket Sequence 题目大意:你有\({cnt}_1,{cnt}_2,{cnt}_3,{cnt}_4\)个"((","()",")(","))",问能否将这些字符串组成一个合法的括号序列. 题解:这一道题,很明显的\({cnt}_2\)是不需要管的,对于第三种情况,它并不改变左右括号的数量差,只有第一.四情况改变,那么,很明显\({cnt}_1={cn

Codeforces Round #350 (Div. 2) E. Correct Bracket Sequence Editor

E. Correct Bracket Sequence Editor Recently Polycarp started to develop a text editor that works only with correct bracket sequences (abbreviated as CBS). Note that a bracket sequence is correct if it is possible to get a correct mathematical express

Codeforces Round #350 (Div. 2) E. Correct Bracket Sequence Editor 线段树模拟

E. Correct Bracket Sequence Editor Recently Polycarp started to develop a text editor that works only with correct bracket sequences (abbreviated as CBS). Note that a bracket sequence is correct if it is possible to get a correct mathematical express

cf3D Least Cost Bracket Sequence

This is yet another problem on regular bracket sequences. A bracket sequence is called regular, if by inserting "+" and "1" into it we get a correct mathematical expression. For example, sequences "(())()", "()" and

cf670E Correct Bracket Sequence Editor

Recently Polycarp started to develop a text editor that works only with correct bracket sequences (abbreviated as CBS). Note that a bracket sequence is correct if it is possible to get a correct mathematical expression by adding "+"-s and "