CF1393E2 - Twilight and Ancient Scroll (Harder Version)
CF1393E2 - Twilight and Ancient Scroll (harder version)
题目大意
给定$n$个串$S_i$,求在每个串中至多删除一个字符(可以删到空)
最终$S’_i$字典序单调不减的方案数
dp
显然是记录上一个串删除的位置$j$,得到$dp_j$,依次考虑每个串
设$S$为当前串,$T$为上一个串
每次我们枚举当前串删除的位置$i$,不妨设得到的新串为$S’$,考虑对于$S’$找到所有合法转移
设$L=LCP(S,T)$,在$T$中删除位置为$t$
1.$t>L+1$
则可以根据$T_{L+1}$和$S’_{L+1}$的关系确定$T’$与$S’$的关系,只需要处理一个后缀和$suf_i$
2.设$p$为$T_{L+1}$向前延伸且字符相同的最长位置,$t\in[p,L+1]$
此时,删除$T_t$可能会使得$L’>L$,所以提出来特殊处理
显然$t\in[p,L+1]\Leftrightarrow t=L+1$,那么对于得到的新串可以再求$LCP(S’,T’)$来判断大小
只需要一个区间和
3.$t<p$,此时$L’=LCP(S’,T’)<L$
由于$L’<L$,比较$S’,T’$相当于比较$T_{t:},T_{t+1:}$
其中$T_{t:}$表示$T$在$t$开始的后缀,那么预处理找到所有合法的$t$,累前缀和即可得到$pre_{p-1}$
关于实现
写$\text{SA,SAM}$就完蛋了
由于删除一个字符之后,求$LCP$的两个串就是在原串基础上进行$\pm 1$的偏移
线性预处理三个$LCP$数组即可,当然真正求的时候需要分类讨论一下(真的,就一下/md)
判断$T_{t:},T_{t+1:}$容易倒着线性预处理出来,在代码里是$chk_i$
所有操作均可以线性处理,时间复杂度为$O(L)$,77ms
Tips:
比较过程中容易出现奇妙的越界,我写得很丑
1 | const int N=1e6+10,P=1e9+7; |