除了 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. python之字典(dict)创建与使用

    字典(dict) 在其他语言中被称为哈希映射(hash map)或者相关数组,它是一种大小可变的键值对集,其中的key.value都是python对象. 特别注意: 1.字典中的key不能重复,key ...

  2. Centos7下vim最新版本安装

    一直以来用的都是vim,因为之前都是系统自带的vim没有研究过怎么自己安装,今天趁着刚装完新系统,顺便装下vim. 同样vim也有两种安装方法: 一.yum安装,centos下安装软件最简单的方法了, ...

  3. C++进阶(智能指针)

    智能指针原理 C++程序设计中使用堆内存是非常频繁的操作,堆内存的申请和释放都由程序员自己管理.程序员自己管理堆内存可以提高了程序的效率,但是整体来说堆内存的管理是麻烦的,C++11中引入了智能指针的 ...

  4. 03-逻辑综合工具 - Design Compiler

    逻辑综合工具DC IC设计流程,市场-->制定spec-->RTL(同时进行sim,通过alint检查RTL有没有错误)-->systhesis(逻辑综合)-->PR(STA) ...

  5. Python面向对象(上)

    Python面向对象(上) python是一门面向对象的编程语言.何为对象?对象是类的实例.在生活中,任何一个事物都是一个对象,如牡丹花.牡丹花的类是花类,同样属于花类的还有荷花.月季花.金银花.菊花 ...

  6. vue小技巧-vue引入样式、修改难以修改的子组件内部标签样式

  7. python命令行参数argparse常用命令

    1.参数个数控制 parser.add_argument('-i', '--integers', nargs='?', const=100, type=int, help='input a numbe ...

  8. Solon v2.0 大版本发布。提效率!降成本!

    一个高效的 Java 应用开发框架:更快.更小.更简单.不是 Spring,没有 Servlet,也无关 JavaEE:新兴独立的开放生态.主框架仅 0.1 MB. 150来个生态插件,覆盖各种不同的 ...

  9. vue3 | isRef、unref、toRef、toRefs

    isRef 检查某个值是否是ref.是返回true,否则返回false. const num = ref(10); const num1 = 20; const num2 = reactive({ d ...

  10. 1月10日内容总结——linux前期知识储备,linux系统、目录、文件相关命令,vi和vim,目录结构

    目录 一.前期必备知识 二.系统运⾏命令 帮助指令 关机/重启命令 三.快捷方式命令 四.⽬录结构与文件相关命令 1.pwd显示当前目录绝对路径指令 2.cd切换到指定目录指令 3.mkdir创建目录 ...