[经典题]括号序列

280 篇文章 1 订阅

题目

题目描述
一个序列的子序列如果是合法括号序列,就称其为 “合括子序列” 。如果一个序列的所有 “合括子序列” 中的最长者,长度恰为 2 k 2k 2k ,则该序列是 “好的” 。求长度为 n n n 的 “好的” 序列个数。

数据范围与提示
数据组数 T ≤ 2 × 1 0 5 T\le 2\times 10^5 T2×105 ,数据范围 2 k ≤ n ≤ 2 × 1 0 5 2k\le n\le 2\times 10^5 2kn2×105

思路

首先要进行一个转换。设 ( + 1 +1 +1) − 1 -1 1 ,设前缀和为 s i s_i si ,则 “合括子序列” 最长者的长度为
n − s n + 2 min ⁡ i = 1 n s i n-s_n+2\min_{i=1}^{n}s_i nsn+2i=1minnsi

理由很简单。在 s i ≥ 0 s_i\ge 0 si0 的情况下,左括号多,必然可以全部匹配。出现问题肯定是第一个 s i = − 1 s_i=-1 si=1 。此时你可以 重新设置零点,因为这个 ) 是无用的,如果 s s s 只统计使用了的括号,后面的 s s s 实际上都要 + 1 +1 +1 才对。于是乎,后面即使再出现 s j = − 1 s_j=-1 sj=1 也是完全匹配的情况。下一个转折点是 s j = − 2 s_j=-2 sj=2 ,又可以重新设置零点。一共有 ∣ min ⁡ s i ∣ |\min s_i| minsi 个转折点,也就有这么多个右括号没有被用到。

最后一截还可能剩余了左括号。最后的剩余左括号数量是 s n s_n sn 吗?错,是 s n + ∣ min ⁡ s i ∣ s_n+|\min s_i| sn+minsi 才对。别忘了我们重新设置了零点的。显然 s n + ∣ min ⁡ s i ∣ s_n+|\min s_i| sn+minsi 为非负整数。所以 n n n 减去二者即是 n − s n − 2 ∣ min ⁡ s i ∣ n-s_n-2|\min s_i| nsn2minsi 为 “合括子序列” 最长的长度。考虑到 min ⁡ s i ≤ 0 \min s_i\le 0 minsi0 就把绝对值符号去掉了而已。

有了这个式子,考虑枚举 t = min ⁡ s i t=\min s_i t=minsi ,此时必然需要
s n = n − 2 k + 2 t s_n=n-2k+2t sn=n2k+2t

如何计算方案数?把 s i s_i si i i i 变化的图像画出来,再把坐标系旋转 4 5 ∘ 45^{\circ} 45 ,这不就是格点图内的移动吗?终止点是 ( n − s n 2 , n + s n 2 ) (\frac{n-s_n}{2},\frac{n+s_n}{2}) (2nsn,2n+sn) 。而 t t t 的限制成为了不能越过 y = x + t y=x+t y=x+t 这条直线,且必须碰触一次。卡特兰的变形嘛。方案数
( n ( n + s n ) / 2 ) − ( n ( n + s n ) / 2 − t + 1 ) {n\choose (n+s_n)/2}-{n\choose (n+s_n)/2-t+1} ((n+sn)/2n)((n+sn)/2t+1n)

别忘了 s n s_n sn t t t 并不是独立的。将 s n s_n sn t t t 替换,你会惊讶的发现第二个组合数内的 t t t 消失了!
( n n − k + t ) − ( n n − k + 1 ) {n\choose n-k+t}-{n\choose n-k+1} (nk+tn)(nk+1n)

为了确保碰触一次,减去没能越过 y = x + t + 1 y=x+t+1 y=x+t+1 这条直线的方案数,即 ( n k − t ) − ( n n − k ) {n\choose k-t}-{n\choose n-k} (ktn)(nkn) 后,我们知道了 t = min ⁡ s i t=\min s_i t=minsi 的方案数是
( n k ) − ( n k − 1 ) {n\choose k}-{n\choose k-1} (kn)(k1n)

你没看错,跟 t t t 无关!而 t t t 的取值是多少呢?只要 y = x + t y=x+t y=x+t 能在 ( 0 , 0 ) (0,0) (0,0) ( n − s n 2 , n + s n 2 ) (\frac{n-s_n}{2},\frac{n+s_n}{2}) (2nsn,2n+sn) 的路径中出现就可以。也就是 f ( n − s n 2 ) ∈ [ 0 , n + s n 2 ] f(\frac{n-s_n}{2})\in[0,\frac{n+s_n}{2}] f(2nsn)[0,2n+sn] f ( 0 ) ≤ 0 f(0)\le 0 f(0)0 。解出
2 k − n ≤ t ≤ 0 2k-n\le t\le 0 2knt0

进而 t t t 的取值数量是 n − 2 k + 1 n-2k+1 n2k+1 ,乘以每个 t t t 的方案数就是答案了。竟然是 O ( 1 ) \mathcal O(1) O(1) 计算,这难道不令人啧啧惊奇吗?

代码

输出 ( n − 2 k + 1 ) ( C n k − C n k − 1 ) (n-2k+1)(C_{n}^{k}-C_{n}^{k-1}) (n2k+1)(CnkCnk1) 你都不会么?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值