大体相同。
CF1750E Bracket Cost
我们能对一个括号序列做以下操作:
- 选择一个子串,将其循环右移一位。比如,
(())
循环右移一位之后变为 )(()
。
- 在括号序列的任意位置加一个左括号或右括号。
记这个括号序列的代价为能将其变为匹配序列的最少操作次数。
给一个括号序列,求其非空子串的代价之和。n≤2×105。
法一
考虑一个括号序列的代价,将匹配的括号删去,则序列形如 )))((
,记 )
有 x 个,(
有 y 个,则使用 min(x,y) 个操作 1 循环位移,∣x−y∣ 次操作 2 补上括号,总次数 max(x,y)。
考虑分别表示出 x,y,记 si 表示前缀 (
个数 - )
个数。
注意到一些匹配的括号和为 0,即不影响前缀和,根据最后序列形如 )))((
,考虑找到左右括号分界处,即为 sl−1,r 的最小值 sx,则之前有 −(sx−sl−1) 个 (
无法匹配,之后有 sr−sx 个 )
无法匹配,所以:
ans=l,r∑max(−(i=l−1minrsi−sl−1),sr−i=l−1minrsi−sl−1)=l,r∑max(sl−1,sr)−i=l−1minrsi=l=0∑nr=l+1∑nmax(sl,sr)−i=lminrsi
前者排序处理,后者单调栈。
桶排即可做到 O(∑n)。
法二
将法一的匹配括号和未匹配括号和起来考虑,设一个序列有 L 个 (
和 R 个 )
,x 对匹配的括号,则代价为 max(L−x,R−x)=max(L,R)−x。
则 ans=l,r∑max(L,R)−x。
对于 ∑max(L,R),有 max(L,R)=2(L+R)+∣L−R∣,维护前缀和,拆开绝对值,容易求。
考虑 ∑x,假设当前一个 )
,找到前面第一个与其匹配的 (
,分别记为 l,r,那么贡献为 l×(n−r+1),即包含这对括号的区间个数。
桶排,复杂度 O(∑n)。
P9356 「SiR-1」Bracket
我们能对一个括号序列做以下操作:
- 将序列循环右移任意位。。
- 在括号序列的任意位置加一个左括号或右括号。
记这个括号序列的代价为能将其变为匹配序列的最少操作次数。
给一个括号序列,求其非空子串的代价之和。n≤2×107。
设一个序列有 L 个 (
和 R 个 )
,x 对匹配的括号,则代价为 ∣L−R∣+[x=min(L,R)]。
前者容易算,对于后者,考虑
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 全程使用 AI 从 0 到 1 写了个小工具
· 快收藏!一个技巧从此不再搞混缓存穿透和缓存击穿
· AI 插件第二弹,更强更好用
· Blazor Hybrid适配到HarmonyOS系统