差点被转卖的题

题目

题目描述
有一只「嘟嘟炎」,它在一个 n × m n\times m n×m 01 01 01 矩阵中随意跳动。它从第 1 1 1 行开始跳,最终跳到第 n n n 行,然后离开。

具体来说,它每次会从第 i    ( i < n ) i\;(i<n) i(i<n) 行的第 a i a_i ai 列跳到第 i + 1 i+1 i+1 行的第 a i + 1 a_{i+1} ai+1 列,且满足 ∣ a i − a i + 1 ∣ ⩽ k |a_i-a_{i+1}|\leqslant k aiai+1k 。而「嘟嘟炎」跳过的位置就会被踩烂,也就是说,它走过的位置会从矩阵中移除,于是就会剩下一个 n × ( m − 1 ) n\times(m-1) n×(m1) 的矩形。

现在请问,对于所有可能的 a i a_i ai,有多少种可能的不同剩余矩阵?两个矩阵不同,当且仅当存在某个位置,在两种情况中这个值不同。

数据范围与提示
n m ⩽ 1 0 6 nm\leqslant 10^6 nm106

思路

首先,每一行的极长连续段中,删掉任意一个都是等效的。

区间 d p \tt dp dp 很容易做到。试着去优化,比如将状态限定为某个极长连续段的前缀或后缀?感觉也比较困难啊。

常用的 d p \tt dp dp 优化不行,就来点阴间的。众所周知 s a sa sa 做 “本质不同子串” 的方法是 n ( n + 1 ) 2 − ∑ i = 1 n − 1 h e i g h t ( i ) \frac{n(n+1)}{2}-\sum_{i=1}^{n-1}height(i) 2n(n+1)i=1n1height(i),为什么只是后缀排名相邻的字符串之间需要减去 l c p \rm lcp lcp 呢?这是因为一种特殊的性质:如果 s a s_a sa 某个前缀与 s b s_b sb 相同,那么二者排名之间的后缀与 s b s_b sb 也有公共前缀。这个是类似于 连通块 的性质:在树上,我们可以用 ∣ E ∣ = ∣ V ∣ − 1 |E|=|V|-1 E=V1 去重;在一维区间 S S S 上,用 ∑ x [ x ∈ S ∧ ( x + 1 ) ∈ S ] = ∣ S ∣ − 1 \sum_{x}[x\in S\wedge (x+1)\in S]=|S|-1 x[xS(x+1)S]=S1 也是同样的道理。

譬如某个子串,一定出现在 r a n k \rm rank rank 为某个区间的后缀中;某两种本质相同的 ⟨ a i ⟩ \langle a_i\rangle ai,某层的可行出发点也构成区间。

于是考虑记 f ( i , j ) f(i,j) f(i,j) a i = j a_i=j ai=j,可以随意确定 a x    ( i < x ) a_x\;(i<x) ax(i<x),不同的剩余矩形数量; g ( i , j ) g(i,j) g(i,j) 则是 f ( i , j ) f(i,j) f(i,j) 的所有可能剩余矩形和 f ( i , j − 1 ) f(i,j-1) f(i,j1) 的所有可能剩余矩形中,有多少个是相同的。那么容易写出转移
f ( i , j ) = ∑ x = j − k j + k f ( i + 1 , x ) − ∑ x = j − k + 1 j + k g ( i + 1 , x ) f(i,j)=\sum_{x=j-k}^{j+k}f(i+1,x)-\sum_{x=j-k+1}^{j+k}g(i+1,x) f(i,j)=x=jkj+kf(i+1,x)x=jk+1j+kg(i+1,x)
这个的原理跟 s a sa sa 是一样的,即 “本质相同的 ⟨ a i ⟩ \langle a_i\rangle ai 在某一层的可行出发点构成区间”。

然而 g ( i , j ) g(i,j) g(i,j) 是怎样转移的呢?其实也就是那些可以同时贡献到 f ( i , j ) f(i,j) f(i,j) f ( i , j − 1 ) f(i,j-1) f(i,j1) 的情况。直觉上,单看上面的 d p \tt dp dp 式,你认为它就是
g ( i , j ) = ∑ x = j − k j + k − 1 f ( i + 1 , x ) − ∑ x = j − k + 1 j + k − 1 g ( i + 1 , x ) g(i,j)=\sum_{x=j-k}^{j+k-1}f(i+1,x)-\sum_{x=j-k+1}^{j+k-1}g(i+1,x) g(i,j)=x=jkj+k1f(i+1,x)x=jk+1j+k1g(i+1,x)
即那些在 d p \tt dp dp 式中可以直接转移到 f ( i , j − 1 ) f(i,j-1) f(i,j1) f ( i , j ) f(i,j) f(i,j) 的。当然必须要 a i , j − 1 = a i , j a_{i,j-1}=a_{i,j} ai,j1=ai,j 才行。

相信你和我有同样的疑惑:为什么 f ( i + 1 , j − 1 − k ) f(i+1,j-1-k) f(i+1,j1k) 贡献到 f ( i , j − 1 ) f(i,j-1) f(i,j1) f ( i + 1 , j + k ) f(i+1,j+k) f(i+1,j+k) 贡献到 f ( i , j ) f(i,j) f(i,j) 就不会重复呢?

……

重新审视一下已知的结论。到底什么是区间啊?所以考虑一个更形式化的证明:两个 ⟨ a i ⟩ \langle a_i\rangle ai 的本质相同,等价于它们在每一行上所删去的元素都属于同一个极长连续段。那么枚举究竟是哪些段(也就枚举了所有可能的剩余矩阵情况),求出 ⟨ a i ⟩ \langle a_i\rangle ai 的可能情况——注意是可行性判断,而非情况数。若 a i + 1 ∈ [ L , R ] a_{i+1}\in[L,R] ai+1[L,R] 可行,那么 a i ∈ [ L − k , R + k ] a_i\in[L-k,R+k] ai[Lk,R+k] 是必要的,还需与当前行所选择的极长连续段取交。于是 a i a_i ai 也属于某个区间,这是充要的。

那么 f ( i , j ) f(i,j) f(i,j) 等价于 a i a_i ai 的可行区间包含 j j j 的情况数,而 g ( i , j ) g(i,j) g(i,j) 就是同时包含 j − 1 j-1 j1 j j j 的。计算方案数都是利用 “连通块容斥” 得出结果。

a i a_i ai 的区间同时包含 j − 1 j-1 j1 j j j,反推回去,就是 a i + 1 ∈ [ j − k , j + k ) a_{i+1}\in[j-k,j+k) ai+1[jk,j+k) 即可。而我们已经说过, ∑ x = l r f ( i , x ) − ∑ x = l + 1 r g ( i , x ) \sum_{x=l}^{r}f(i,x)-\sum_{x=l+1}^{r}g(i,x) x=lrf(i,x)x=l+1rg(i,x) 就代表了 a i a_i ai 的可行区间与 [ l , r ] [l,r] [l,r] 有交的情况数,所以就有了上文 g ( i , j ) g(i,j) g(i,j) 的递推式。

说白了就是那种问题:求 ∣ { x    ∣    ∃ y ,    P ( x , y ) } ∣ \Big|\{x\;|\;\exists y,\;P(x,y)\}\Big| {xy,P(x,y)},转为求 ∑ x P ( x , y ) \sum_{x}P(x,y) xP(x,y) 然后对 y y y 容斥。如果是指数级容斥即是 [NOI2021] 机器人游戏 一类,如果是 “连通块容斥” 即是 [十二省联考2019]希望 一类。

都是前缀和简单 d p \tt dp dp 转移,时间复杂度 O ( n m ) \mathcal O(nm) O(nm)

代码

没得代码。但是简单说一句:初状态是 f ( n , j ) = 1 f(n,j)=1 f(n,j)=1 g ( n , j ) = [ a n , j − 1 = a n , j ] g(n,j)=[a_{n,j-1}=a_{n,j}] g(n,j)=[an,j1=an,j]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值