除了 L 神 txdy 我还能说啥呢。(L 神把这题搬模拟赛了。。。)

即把每个 x 换成 (),问是否能通过不多于一次区间反转(() 交换)后合法。

考虑怎样的括号串是合法的。

假设左括号为 \(a_p=0\),右括号为 \(a_p=1\),标号 \(0\sim n-1\)。

我们设 \(S_r=\sum_{k<r}(-1)^{a_k}\),则一个串合法当且仅当

\[S_p\ge0\land S_n=0
\]

容易发现只要 \(\{S_k\}\) 不同则不同,我们构造了一个 \(S\) 和括号串的双射。(折线法!)

现在再考虑反转操作。

假设反转 \([l,r)\)。

\[S_p\ge0\quad(p\le l)
\]
\[S_l-(S_p-S_l)\ge0\quad(l<p\le r)
\]
\[S_l-(S_r-S_l)+(S_p-S_r)\ge0\quad(r<p)
\]
\[S_l-(S_r-S_l)+(S_n-S_r)=0
\]

化简代换一下,也即

\[S_p\ge0\quad(p\le l)
\]
\[S_p\le2S_l\quad(l<p\le r)
\]
\[S_p\ge S_n\quad(r<p<n)
\]
\[S_n=2(S_r-S_l)
\]

考虑到直接 dp 可能会计重(合法的 \(l,r\) 不唯一),考虑如何避免计重。

一般来说,避免计重可以通过对条件的贪心化实现,也即对每种方案确定某种最优的 \((l,r)\) 对。

假设 \(l\sim r\) 间最大 \(S\) 为 \(S_{\max}\),容易发现 \(S_{\max}\le2S_l\)。

考虑对 \(S_n\) 分类讨论。

当 \(S_n>0\) 时,假设存在 \(S_p<0\),取 \(S_l=\lceil S_{\max}/2\rceil\) 总是不妨最优(顺带一提,\(2\le S_n\le S_r=S_l+S_n/2\le S_{\max}\le2S_l\));也即 \(2S_l-1\le S_{\max}\le2S_l\)。并且总是取最后一个可能的 \(l\),因此下次枚举到一个 \(S_p=S_l\) 时要查看 \(S_l\sim S_p\) 区间内有无 \(S<0\),倘没有则总是不得转移。可以证明这样的 \(l\) 总是最优且唯一。

区间合法遇到 \(r\) 时,我们总应使区间内最大数在 \(2S_l-1\sim2S_l\) 间,且存在 \(S_p<0\)。

由于可能会有另一个合法的 \(S_{r'}=S_r\) 在当前 \(S_r\) 后,考虑如何避免:考虑强制令到下一次出现 \(S_{r'}=S_r\) 之前有某个 \(S_p=2S_l+1\),或一直到 \(S_n\) 均无另一个 \(S_{r'}=S_r\) 则可行,否则不可行。容易发现不会漏统计情况,也不会计重。

第二类情况的计算可以考虑倒推,记录当前 \(S_r-S_n\) 和目前最大 \(S_r-S_n\),可以 \(O(n^3)\) 预处理。

对于第一类情况,即考虑枚举下次出现 \(S_p=2S_l+1\) 的时间来计算方案数,这个可以倒推预处理。通过预处理从 \(n\) 到 \(p\),保持 \(S_p-S_n\ge0\),当前 \(S_p-S_n\) 为某值的方案数,以及进一步到 \(S_v-S_n\),其间所有 \(S_l-S_n<S_k-S_n<S_p-S_n\),直至开头为某数的方案数,来暴力计算。这是 \(O(n^4)\) 的,并且很难优化。

考虑到这么做复杂度不优,我们略做修改,不枚举 \(r\),而是对区间内最大值容斥,枚举何时出现超过最大值边界的元素,这样此前所有可能的 \(S_r\) 均可以出现,从而无需对 \(r\) 端点去重。特别地,如果到终点均未出现超过边界的元素,这类贡献我们还是用先前第二类预处理的方式计算。

这样会好写一点,并且避免了复杂度不优的问题。

对于 \(S_p\ge0\) 恒成立的情况,我们考虑另写一个 dp 判断。

类似于刚刚的 dp,但是区间内不能出现与 \(S_l\) 相等的数。

考虑设 \(x\) 为最大的满足 \(S_x-S_n<0\) 的数,则取 \(r\) 为最大的满足 \(S_r-S_n=\min\{S_k-S_n|x<k\le n\}\) 即可。

只用计算这样的合法方案数即可,与上面过程是类似的。

只用找一个 \(l\) 满足 \(S_l=S_r-S_n/2\),且 \(S_{\max}\le2S_l\) 即可。显然这样的 \(l\) 越大越好,因此区间内不能有和目前 \(S_l\) 一样大的数,也即所有数均大于 \(S_l\)。

容易发现把前面的 dp 过程中未出现负数的方案也用来计算答案即可。

但是这样会算重,所以观察性质,容易发现某些情况的充要条件是 \(\max\{S_k|x<k\le n\}\ge2S_n\),然后就完了。

这样我们就讨论完了 \(S_n>0\) 的情况。

而 \(S_n<0\) 和 \(S_n>0\) 就差一个全局翻转,翻过来一样做即可。

考虑 \(S_n=0\),这个的合法条件是什么?

如果 \(S_p\ge0\) 恒成立,显然总可行。

否则,我们设 \(x\) 是第一个 \(S_x<0\),\(y\) 是最后一个 \(S_y<0\),则合法等价于

\[\max\{S_k|x\le k\le y\}\le2\min\{\max\{S_k|k<x\},\max\{S_k|k>y\}\}
\]

于是同样 dp 即可。

总复杂度容易做到 \(O(n^3)\)。

重新理一遍。

先考虑 \(S_n>0\) 的情况的答案。

由于刚刚的过程过于抽象,我们用 dp 方程来描述这一做法。

对于 \(\texttt x\),我们认为其 \(a_p\) 在过程中既可以为 \(0\),也可以为 \(1\),相当于是做两轮转移。

设 \(f_{m,v}\) 为已考虑前 \(m\) 项,其 \(S_p\ge0\) 均成立,且 \(S_m=v\) 的方案数。

显然有(\(\leftarrow\) 表示 dp 的贡献转移方向,不是赋值

\[f_{0,v}=[v=0]
\]
\[f_{m+1,v+1}\leftarrow[a_m=0]f_{m,v}
\]
\[f_{m+1,v-1}\leftarrow[a_m=1][v>0]f_{m,v}
\]

同样的,设 \(g_{m,v}\) 为已考虑 \(m\sim n\) 项,其 \(S_p-S_n\ge0\) 均成立,且 \(S_m-S_n=v\) 的方案数。

\[g_{n,v}=[v=0]
\]
\[g_{m+1,v+1}\leftarrow[a_m=1]g_{m,v}
\]
\[g_{m+1,v-1}\leftarrow[a_m=0][v>0]g_{m,v}
\]

我们类似地维护后缀、后缀最大值的 dp,方法类似。

假设 \(h_{m,L,v,0/1}\) 为已考虑 \(0\sim m\) 项,\(S_l=L\),\(S_m=v\),区间内是否已出现负数。

计算两遍,第一遍要求 \(v\le2L\),第二遍要求 \(v\le2L-2\)。

遇到 \(v>2L\) 或者 \(v>2L-2\) 的元素可以直接计算对答案的贡献,注意特判 \(L=1\)。

然后分类计算贡献即可。dp 不予列出。

\(S_p<0\) 同理。

\(S_p=0\) 的部分,分类左侧小还是右侧小,分别写一遍即可。

虽然但是,L 神 txdy!

代码写了 13k。。。

loj2839的更多相关文章

随机推荐

  1. 三步快速搭建Typora图床(SM.MS+PicGo)

    三步快速搭建Typora图床(基于SM.MS+PicGo) 前言 在有些同学使用Typora的过程中,会发现Typora不像Word一样,在文档脱离本机后依然正常显示图片,自己的tyopora文件在发 ...

  2. 4、Idea设置显示多行文件

    使用IDEA时,可能会没有注意到,一旦打开过多的Java文件时,默认会堆积在一行显示,就像浏览器打开了多个标签一样,此时需要通过右侧箭头筛选的方式来选择其他文件.为了解决这一问题,需要打开多行显示的方 ...

  3. [python] 基于matplotlib实现圆环图的绘制

    圆环图本质上是一个中间切出一块区域的饼状图.可以使用python和matplotlib库来实现.本文主要介绍基于matplotlib实现圆环图.本文所有代码见:Python-Study-Notes # ...

  4. day05-Spring管理Bean-IOC-03

    Spring管理Bean-IOC-03 2.基于XML配置bean 2.15bean的生命周期 bean对象的创建是由JVM完成的,然后执行如下方法: 执行构造器 执行set相关方法 调用bean的初 ...

  5. 跟AWS学极致服务

    春节期间,除了还在看技术书籍外,我一直抽空断断续续地在看<极致服务:创造不可思议的客户体验>一书.之前创业的经历,让我一直反思,除了赛道和落地之外,是否在服务质量上也有缺失. 书里从一个商 ...

  6. SpringCloud NetFlix学习

    SpringCloud NetFlix 遇到记录不完全的可以看看这个人的博客 学相伴SpringCloud 微服务架构的4个核心问题? 服务很多,客户端该怎么访问? 负载均衡.反向代理,用户请求的永远 ...

  7. 读Java8函数式编程笔记02_流

    1. 外部迭代 1.1. for循环是一个封装了迭代的语法糖 1.1.1. 本质上来讲是一种串行化操作 1.2. 很难抽象出不同操作 2. 内部迭代 2.1. 内部迭代中的相应接口:Stream 2. ...

  8. SkyWalking安装及SkyApm运行(.net和java)

    一.部署SkyWalking 1.下载SkyWalking包(版本为6.6.0) 下载地址为:http://skywalking.apache.org/downloads/ 2.修改数据库配置 默认为 ...

  9. Spring异步Async和事务Transactional注解

    Spring开发中我们我们常常用到@Transaction和@Async,但这2个注解加在一起很多的开发者不敢用,担心事务不生效.下面我们就仔细讲解一下这2个注解同时运用,文章用3个场景讲述它们之间的 ...

  10. 简述 Gin 框架如何集成swagger

    https://blog.csdn.net/raogeeg/article/details/86743953 @Title           这个 API 所表达的含义,是一个文本,空格之后的内容全 ...