loj2839
除了 L 神 txdy 我还能说啥呢。(L 神把这题搬模拟赛了。。。)
即把每个 x 换成 ( 或 ),问是否能通过不多于一次区间反转(( 与 ) 交换)后合法。
考虑怎样的括号串是合法的。
假设左括号为 \(a_p=0\),右括号为 \(a_p=1\),标号 \(0\sim n-1\)。
我们设 \(S_r=\sum_{k<r}(-1)^{a_k}\),则一个串合法当且仅当
\]
容易发现只要 \(\{S_k\}\) 不同则不同,我们构造了一个 \(S\) 和括号串的双射。(折线法!)
现在再考虑反转操作。
假设反转 \([l,r)\)。
则
\]
\]
\]
\]
化简代换一下,也即
\]
\]
\]
\]
考虑到直接 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\),则合法等价于
\]
于是同样 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 的贡献转移方向,不是赋值)
\]
\]
\]
同样的,设 \(g_{m,v}\) 为已考虑 \(m\sim n\) 项,其 \(S_p-S_n\ge0\) 均成立,且 \(S_m-S_n=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的更多相关文章
随机推荐
- matlab狄拉克锥的三维图
石墨烯(graphene)中的狄拉克锥(Dirac cone)图形.直接按照能级公式绘图,公式参考[1]中 energy of the electrons 公式. %matlab代码 clear; g ...
- Kubernetes的垂直和水平扩缩容的性能评估
Kubernetes的垂直和水平扩缩容的性能评估 译自:Performance evaluation of the autoscaling strategies vertical and horizo ...
- 什么是Rabbitmq消息队列? (安装Rabbitmq,通过Rabbitmq实现RPC全面了解,从入门到精通)
目录 Rabbitmq 一: 消息队列介绍 1.介绍 2.MQ解决了什么问题 1.应用的解耦 2.流量削峰 3.消息分发(发布订阅: 观察者模式) 4.异步消息(celery就是对消息队列的封装) 3 ...
- [编程基础] C++多线程入门6-事件处理的需求
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 6 事件处 ...
- 如何用 30s 给面试官讲清楚什么是 Session-Cookie 认证
引言 由于 HTTP 协议是无状态的,完成操作关闭浏览器后,客户端和服务端的连接就断开了,所以我们必须要有一种机制来保证客户端和服务端之间会话的连续性,也称为认证,最常见的应用场景就是保持用户的登录态 ...
- 精华推荐 | 【JVM深层系列】「GC底层调优系列」一文带你彻底加强夯实底层原理之GC垃圾回收技术的分析指南(GC原理透析)
前提介绍 很多小伙伴,都跟我反馈,说自己总是对JVM这一块的学习和认识不够扎实也不够成熟,因为JVM的一些特性以及运作机制总是混淆以及不确定,导致面试和工作实战中出现了很多的纰漏和短板,解决广大小伙伴 ...
- angular组件共用服务打印日志父子组件传值2创建服务注入
- 解决安装node-sass报错的方法
1.下载源码放到本地搞~~ 适合内网开发的苦孩子们~~~ 先进入https://github.com/sass/node-sass/releases下载自己需要的包 可以点击tags然后找到自己需要的 ...
- C#高性能数组拷贝实验
前言 昨天 wc(Wyu_Cnk) 提了个问题 C# 里多维数组拷贝有没有什么比较优雅的写法? 这不是问对人了吗?正好我最近在搞图像处理,要和内存打交道,我一下就想到了在C#里面直接像C/C++一样做 ...
- 【学习笔记】C/C++ 设计模式 - 工厂模式(下)
介绍说明 这篇笔记承接<[学习笔记]C/C++ 设计模式 - 工厂模式(上)>文章,主要记录 "抽象工厂设计模式" 的学习笔记,上一次是以音频播放器来作为例子,主要是想 ...