Codeforces 1239B. The World Is Just a Programming Task (Hard Version)
这一题好妙啊
首先把括号序列转化成平面直角坐标系 $xOy$ 上的折线,初始时折线从坐标系原点 $(0,0)$ 出发
如果第 $i$ 个位置是 '(' 那么折线就往上走一步($y+1$),否则往下走一步 ($y-1$)
这条折线有很多有用的性质
$1.$如果某个时刻折线的纵坐标为负数了,那么说明这个括号序列一定是不合法的
证明也挺好理解的,变成负数说明没有足够的 '(' 和 ')' 匹配了,显然不合法
$2.$如果最终位置 $n$ 的折线 $y$ 坐标不为 $0$ ,那么一定不合法,因为这样说明 '(' 和 ')' 数量不相等
$3.$如果以上两条都不满足,那么括号序列合法,证明应该是挺显然的吧,即任何位置的 ')' 都能得到匹配并且最后全部匹配完毕
并且可以发现,在保证最终位置折线 $y$ 坐标为 $0$ 的情况下,这个括号序列的不同循环移位的合法序列数即为 这些到达最小值的位置数
设这些位置的序列为 $p$
对初始序列进行循环移位 $p_1,p_2,p_3...$ 后括号序列是合法的,并且其他的循环移位后都不合法
证明首先设 $a_1,a_2,a_3...a_n$ 是初始时的括号序列
那么对于循环移位 $p$ ,相当于把序列 $a$ 变成 $a_{p+1}a_{p+2}...a_{n}a_{1}a_{2}a_{3}...a_{p}$
那么假设原本折线在位置 $p$ 时的 $y$ 的值为 $t$ (显然 $t<=0$)
那么对于 $(p,n]$ 的这一段折线,显然它的形状不会变,并且 $y$ 坐标同时增加 $-t$
这个挺好理解的吧,首先 $p$ 位置的 $y$ 变成 $0$ ,后面的就和 $p$ 位置一起变了
然后 $[0,p]$ 这一段折线再接到原本位置 $n$ 的后面(显然这一段折线也增加了 $-t$),看图理解吧:



上图展示了循环移位 $p1$ 后折线的变化
由于 $t$ 是初始折线最小的纵坐标,那么循环移位后就不存在任何位置的 $y$ 小于 $0$
由上图你会发现所有的 $y$ 都增加了 $-t$,又因为折线的形状不变所以所有位置的 $y$ 都大于等于 $0$
然后又因为最终位置的 $y$ 一定为 $0$(由于初始时位置 $n$ 的 $y$ 为 $0$,那么左右括号数量永远相等,不管怎么循环移位最终位置都是 $y=0$)
那么说明这一段循环移位后括号序列一定是合法的(由之前证明的第 $3$ 条可得)
现在只剩下证明其他的循环移位都不合法即可,其实十分显然,因为从其他位置循环移位后坐标增加量不到 $-t$
那么对于初始为 $t$ 的位置增加后还是小于 $0$,还是不合法
所以我们经历了千辛万苦终于证明了官方题解里一句话的东西:
It can easily be shown that the answer to the question of the number of cyclic shifts being correct bracket sequence is the number of times how much minimum balance is achieved in the array of prefix balances.

如果此时你理解了循环移位对于折线的变化,那么就很容易知道交换两个位置对折线的变化
如果交换 ')' 和 '(' ,会导致一段区间的 $y$ 加 $2$ ,那么对答案毫无意义,只会让答案变小
所以只能交换 '(' 和 ')' ,那么会导致区间的 $y$ 减 $2$,如果你改变的区间跨过了某个 $p_i$ ($p_i$ 的定义同上)
那么只会让答案更小,因为此时只有跨过的 $p$ 会产生贡献,还不如原本更多的 $p$
为了方便,现在让我们把折线用循环移位变成任意时刻都大于等于 $0$ 的情况(显然对任意一个 $p_i$ 进行循环移位 $p_i$ 即可)
此时所有初始位置为 $p$ 的位置的 $y$ 均为 $0$,设此时 $y$ 为 $0$ 的位置为新的序列 $p$
因为之前证明的,交换只能在区间 $(p_i,p_{i+1})$ 进行,如果我们把 $p_{i}+1$ (显然是 '(')和 $p_{i+1}$ 交换(显然是 ')')
那么区间内所有 $y$ 值为 $1$ 的位置因为减 $2$ 就变成了最小的位置(区间内不存在 $y=0$ 的位置),那么交换以后序列的答案即为初始这一段区间内 $1$ 的个数
为了答案最大我们显然只要考虑 $(p_i,p_{i+1})$ 区间内 $1$ 的个数
然后考虑把 $y=2$ 的位置通过减 $2$ 变成 $0$ ,那么答案就是初始时的答案加上区间内 $y=2$ 的贡献(注意此时区间内不能有 $0,1$)
我们同样可以找到这些位置,然后操作一下看看答案是多少即可,实现起来还是有点细节的
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=3e5+;
int n,cnt,sl,sr,sum[N];
char s[N],tmp[N];
int main()
{
n=read(); scanf("%s",s+);
int pos=,now=,mi=;
for(int i=;i<=n;i++)
{
now+=s[i]=='(' ? : -;
if(now<mi) mi=now,pos=i;
}
if(now!=) { printf("0\n1 1\n"); return ; }
for(int i=;i<=n;i++) tmp[i]=s[ (pos+i-)%n+ ];
vector <int> V; V.push_back();
for(int i=;i<=n;i++)
{
s[i]=tmp[i]; sum[i]=sum[i-] + (s[i]=='(' ? : -);
if(!sum[i]) cnt++,V.push_back(i);
}
int ans=cnt,L=,R=,len=V.size();
for(int i=;i<len;i++)
{
int l=V[i-]+,r=V[i],t=;
for(int j=l;j<=r;j++) t+=sum[j]==;
if(t>ans) ans=t,L=l,R=r;
}
V.clear(); for(int i=;i<=n;i++) if(sum[i]==) V.push_back(i);
len=V.size();
for(int i=;i<len;i++)
{
int l=V[i-]+,r=V[i],t=cnt;
if(sum[l]==) continue;//如果sum[l]不为0,那么sum[l]一定为2,那么下一个sum为1的位置一定为r,即[l,r)之间不存在sum为0或1的位置
for(int j=l;j<=r;j++) t+=sum[j]==;
if(t>ans) ans=t,L=l,R=r;
}
printf("%d\n%d %d\n",ans,(L+pos-)%n+,(R+pos-)%n+);
return ;
}
Codeforces 1239B. The World Is Just a Programming Task (Hard Version)的更多相关文章
- Codeforces Round #594 (Div. 1) D2. The World Is Just a Programming Task (Hard Version) 括号序列 思维
D2. The World Is Just a Programming Task (Hard Version) This is a harder version of the problem. In ...
- codeforces#1248D2. The World Is Just a Programming Task(括号匹配转化为折线处理)
题目链接: http://codeforces.com/contest/1248/problem/D2 题意: 可以执行一次字符交换的操作 使得操作后的字符串,循环移位并且成功匹配的方案最多 输出最多 ...
- [cf 1239 B] The World Is Just a Programming Task (Hard Version)
题意: 给你一个长度为n的括号序列,你可以交换其中的两个元素,需要使该序列的n个循环移位中合法的括号序列个数尽量多. 输出最大的答案以及交换哪两个元素能够取到这个答案. $n\leq 3\times ...
- CF The World Is Just a Programming Task (Easy Version)【分析·思维】
题目传送门 题意: 给定一个括号序列,随意交换两个位置的括号之后,问有多少个不同长度的圈.关于圈的定义大概就是:将括号序列的后$k$个数放到括号序列的最前面,就是长度为$k$的圈.(看了好久题意emm ...
- Codeforces Round #312 (Div. 2) E. A Simple Task 线段树
E. A Simple Task 题目连接: http://www.codeforces.com/contest/558/problem/E Description This task is very ...
- 并不对劲的CF1239B&C&D Programming Task in the Train to Catowice City
CF1239B The World Is Just a Programming Task 题目描述 定义一个括号序列s是优秀的,当且仅当它是以下几种情况的一种: 1.|s|=0 2.s='('+t+' ...
- Codeforces 801 A.Vicious Keyboard & Jxnu Group Programming Ladder Tournament 2017江西师大新生赛 L1-2.叶神的字符串
A. Vicious Keyboard time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- Codeforces Gym100814 F.Geometry (ACM International Collegiate Programming Contest, Egyptian Collegiate Programming Contest (2015) Arab Academy for Science and Technology)
这个题真的是超级超级水啊,哈哈哈哈哈哈.不要被题面吓到,emnnn,就这样... 代码: 1 #include<iostream> 2 #include<cstring> 3 ...
- Codeforces Round #594 (Div. 2) D1 - The World Is Just a Programming Task
思路:枚举换的位置i,j 然后我们要先判断改序列能否完全匹配 如果可以 那我们就需要把差值最大的位置换过来 然后直接判断就行
随机推荐
- (4.1)打造简单OS-小实验[图形显示]
主要是实现<简单打造OS>第四小节说到的一个图形界面的实验项目 1.mbr boot.inc ;------------- loader和kernel ---------- LOADER_ ...
- @Aspect注解并不属于@Component的一种
也就是一个类单纯如果只添加了@Aspect注解,那么它并不能被context:component-scan标签扫描到. 想要被扫描到的话,需要追加一个@Component注解
- 仿站技术——获取和使用某些网站的iconfont图标字体
前言: 很多前端新手在仿一些大型网站的时候经常遇到一个问题:该网站使用了图标字体——iconfont,虽然现在阿里有开源的iconfont库,但是还是没有原网站的效果(本人强迫症但非处女座).所以此文 ...
- 【Java 8】巧用Optional之优雅规避NPE问题
避之不及的 NullPointerException NPE : NullPointerException 空指针异常是最常见的Java异常之一,抛出NPE错误不是用户操作的错误,而是开发人员的错误, ...
- Linux设置开机挂载
Linux可不可以在开机的时候就将我们要的文件系统都挂载好?这样就不需要每次进入Linux系统还要挂载一次.当然可以,那就直接到/etc/fstab里面去修改. 系统挂载的一些限制: - 根目录/是必 ...
- mongodb设置 十个要点
mongodb设置 十个要点 一.对象ID的生成 每一个mongoDB文档那个都要求有一个主键.它在每一个集合中对全部的文档必须是唯一的.主键存放在文档_id字段中.由12个字符组成: 4c291 ...
- SQL Server 变量定义
declare @id intdeclare @name char(10) --注意:char(10)为10位,要是位数小了会让数据出错set @id=1 set @name='sssss'selec ...
- activiti 术语 国际化文件
activiti-explorer editor-app 国际化文件 - 大强的博客 - CSDN博客https://blog.csdn.net/daqiang012/article/details/ ...
- [转]vscode 插件推荐 - 献给所有前端工程师(2019.8.7更新)
原文地址:https://segmentfault.com/a/1190000006697219 VScode现在已经越来越完善.性能远超Atom和webstorm,你有什么理由不用它?在这里,我会给 ...
- 从安装PHP到第一个tomcat执行的hello world其实没那么难
001 初入门的朋友问我为什么她的PHP老是不能安装运行成功,作为一个乐(shi)于(li)助(liao)人(mei)的半程序员, 自然是要好好研究然后手把手教妹纸了! 002 话不多说,进入正题 为 ...