题意
做法
这里字符集为([0,9))
令(f_{i,j})为前(i)个字符,以(j)结尾的本质不同个数,显然
我们将其写成(10 imes 10)矩阵的形式,格外将长度(+1)来保存常数(1)
(M_i)表示字符为(i)的转移矩阵,其在单位矩阵的基础上,第(i)列全为(1)
对于([l,r])的询问,答案为
令(I_1=egin{pmatrix}0&0 & 0 & cdots & 0 & 1end{pmatrix}),(I_2=egin{pmatrix}1&1 & 1 & cdots & 1end{pmatrix}^T)
我们将其拆分成两部分来维护:
(I_1cdot M_{s_{l-1}}^{-1}M_{s_{l-2}}^{-1}cdots M_{s_1}^{-1})
(M_{s_1}M_{s_2}cdots M_{s_r}cdot I_2)
我们对于所有的(iin[0,n]),预处理出上面的两部分
(A_1=I_1M_{s_{i-1}}^{-1}M_{s_{i-2}}^{-1}cdots M_{s_1}^{-1})
(A_2=M_{s_1}M_{s_2}cdots M_{s_i}cdot I_2)
对于第一部分
由于(I_1)仅有第(9)行有效
那么我们其实没必要将整个({A_1})存下来,仅需知道每个矩阵最后一行即可
当我们(A)左乘上(M_c^{-1}),观察会发生什么变化
第(i)列整体减去(A_{c,i})((i
eq c))
第(c)列不发生变化
我们对矩阵(A)维护一个矩阵(A'),且每一列维护(tag_i),表示(A_{i,j}=A'_{i,j}+tag_j)
假设当前某一列为(egin{pmatrix}a_0+tag_i,a_1+tag_i,cdots,a_c+tag_i,cdots,a_{9}+tag_iend{pmatrix}^T)
那么其将变成:(egin{pmatrix}a_0-a_c,a_1-a_c,cdots,a_c+tag_i,cdots,a_{9}-a_cend{pmatrix}^T)
将(a_c+tag_i)改写成((2a_c+tag_i)-a_c)
那么我们仅需对(A)每一行的((i,c))位置,以及({tag_i})修改,即可维护出最后一行
对于第二部分
最后会将矩阵乘上(I_2),这个的意义是每一行之和
那么我们其实没必要将整个({A_2})存下来,仅需知道每个矩阵的列向量(A')((A'_i)为(A_i)第(i)行之和)
当我们(A)右乘上(M_c),观察会发生什么变化
对于(A_{i,c}(iin[0,9])),其修改为第(i)行之和;其他位置不变
那么每次(A)一行中只会有一个位置发生变化
我们在维护(A)的同时很容易预处理出列向量(A')
时间复杂度(O(10(n+q)))
code
可能上面讲的有点绕,可以看下代码
code