题目链接
题意
输入两个字符串$s$,$t$,且$S$串每个位置有权值$f(i)$,定义$Sval$为$S$串(所有匹配$T$串某一个位置)的子串的右端点权值的和。$q$次操作:
1.把 改为。
2.询问$T$子串的$Sval$。
思路
这题理解了好久,可能还没理解透彻。先整理下思路,后面更新代码。
总的来说是一道码量惊人的题目。
后缀自动机
实现匹配,我们很容易想到后缀自动机,首先将$S$拼接在$T$后面(反过来也行),建出的后缀自动机,但是由于这题权值定义为右端点,如果用后缀去搞,我们明显更容易确定左端点,所以我们在建串的时候先把两个串反过来。
那么能够匹配$T$串某一个子串的$S$串起始位置在后缀树组上其实是一段连续的区间,我们现在要求的其实就是这段区间里其实位置在$S$串要求范围里的$f$值。
RMQ
首先我们来看一下怎么找这个区间,利用后缀数组,我们可以知道两个不同位置开始的后缀的$lcp$,我们可以在上面两次二分,找出最大的能够匹配整个要求的$T$子串的范围。怎么check呢?回想我们以前后缀数组的套路,无非就是RMQ一下,看看整个区间是不是height最小值大于等于我们要的长度。
树套数
我们现在已经利用RMQ知道了这个后缀数组中的区间在哪里,现在要做的就是求和。
也就是
如果只是普通求$f$和我们一个线段树或树状数组就可以解决,现在还有一维范围要求,那么我们可以树套数解决这个问题。
树状数组的每个点都是一棵线段树,按照sa的顺序往线段树里面加点,这样就可以求出一个后缀数组区间里指定范围内的权值和。
蔡队代码,具体可见wiki
1 |
|