loj2839

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

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

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

假设左括号为 ap=0,右括号为 ap=1,标号 0n1

我们设 Sr=k<r(1)ak,则一个串合法当且仅当

Sp0Sn=0

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

现在再考虑反转操作。

假设反转 [l,r)

Sp0(pl)

Sl(SpSl)0(l<pr)

Sl(SrSl)+(SpSr)0(r<p)

Sl(SrSl)+(SnSr)=0

化简代换一下,也即

Sp0(pl)

Sp2Sl(l<pr)

SpSn(r<p<n)

Sn=2(SrSl)

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

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

假设 lr 间最大 SSmax,容易发现 Smax2Sl

考虑对 Sn 分类讨论。

Sn>0 时,假设存在 Sp<0,取 Sl=Smax/2 总是不妨最优(顺带一提,2SnSr=Sl+Sn/2Smax2Sl);也即 2Sl1Smax2Sl。并且总是取最后一个可能的 l,因此下次枚举到一个 Sp=Sl 时要查看 SlSp 区间内有无 S<0,倘没有则总是不得转移。可以证明这样的 l 总是最优且唯一。

区间合法遇到 r 时,我们总应使区间内最大数在 2Sl12Sl 间,且存在 Sp<0

由于可能会有另一个合法的 Sr=Sr 在当前 Sr 后,考虑如何避免:考虑强制令到下一次出现 Sr=Sr 之前有某个 Sp=2Sl+1,或一直到 Sn 均无另一个 Sr=Sr 则可行,否则不可行。容易发现不会漏统计情况,也不会计重。

第二类情况的计算可以考虑倒推,记录当前 SrSn 和目前最大 SrSn,可以 O(n3) 预处理。

对于第一类情况,即考虑枚举下次出现 Sp=2Sl+1 的时间来计算方案数,这个可以倒推预处理。通过预处理从 np,保持 SpSn0,当前 SpSn 为某值的方案数,以及进一步到 SvSn,其间所有 SlSn<SkSn<SpSn,直至开头为某数的方案数,来暴力计算。这是 O(n4) 的,并且很难优化。

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

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

对于 Sp0 恒成立的情况,我们考虑另写一个 dp 判断。

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

考虑设 x 为最大的满足 SxSn<0 的数,则取 r 为最大的满足 SrSn=min{SkSn|x<kn} 即可。

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

只用找一个 l 满足 Sl=SrSn/2,且 Smax2Sl 即可。显然这样的 l 越大越好,因此区间内不能有和目前 Sl 一样大的数,也即所有数均大于 Sl

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

但是这样会算重,所以观察性质,容易发现某些情况的充要条件是 max{Sk|x<kn}2Sn,然后就完了。

这样我们就讨论完了 Sn>0 的情况。

Sn<0Sn>0 就差一个全局翻转,翻过来一样做即可。

考虑 Sn=0,这个的合法条件是什么?

如果 Sp0 恒成立,显然总可行。

否则,我们设 x 是第一个 Sx<0y 是最后一个 Sy<0,则合法等价于

max{Sk|xky}2min{max{Sk|k<x},max{Sk|k>y}}

于是同样 dp 即可。

总复杂度容易做到 O(n3)

重新理一遍。

先考虑 Sn>0 的情况的答案。

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

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

fm,v 为已考虑前 m 项,其 Sp0 均成立,且 Sm=v 的方案数。

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

f0,v=[v=0]

fm+1,v+1[am=0]fm,v

fm+1,v1[am=1][v>0]fm,v

同样的,设 gm,v 为已考虑 mn 项,其 SpSn0 均成立,且 SmSn=v 的方案数。

gn,v=[v=0]

gm+1,v+1[am=1]gm,v

gm+1,v1[am=0][v>0]gm,v

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

假设 hm,L,v,0/1 为已考虑 0m 项,Sl=LSm=v,区间内是否已出现负数。

计算两遍,第一遍要求 v2L,第二遍要求 v2L2

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

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

Sp<0 同理。

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

虽然但是,L 神 txdy!

代码写了 13k。。。

posted @   myee  阅读(42)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
点击右上角即可分享
微信分享提示