loj6074

题意

loj

做法

这里字符集为\([0,9)\)
\(f_{i,j}\)为前\(i\)个字符,以\(j\)结尾的本质不同个数,显然

\[\begin{cases} f_{i,j}=f_{i-1,j}&j\neq c_i\\ f_{i,c_i}=\sum\limits_{j}f_{i-1,j}+1 \end{cases} \]

我们将其写成\(10\times 10\)矩阵的形式,格外将长度\(+1\)来保存常数\(1\)
\(M_i\)表示字符为\(i\)的转移矩阵,其在单位矩阵的基础上,第\(i\)列全为\(1\)

\[\begin{aligned} M_i = \begin{pmatrix}1 & & 1 & & \\ & 1 & 1 & & \\ & & 1 & & \\ & & \vdots & \ddots & \\ & & 1 & & 1 \end{pmatrix} \\\end{aligned}\]

对于\([l,r]\)的询问,答案为

\[\begin{pmatrix}0&0 & 0 & \cdots & 0 & 1\end{pmatrix}\prod\limits_{i=l}^r M_{s_i}\begin{pmatrix}1 \\ 1 \\ 1 \\ \vdots \\ 1 \end{pmatrix} \]

\(I_1=\begin{pmatrix}0&0 & 0 & \cdots & 0 & 1\end{pmatrix}\)\(I_2=\begin{pmatrix}1&1 & 1 & \cdots & 1\end{pmatrix}^T\)

我们将其拆分成两部分来维护:
\(I_1\cdot 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\)

我们对于所有的\(i\in[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\)

\[\begin{aligned} M_i^{-1} = \begin{pmatrix}1 & & -1 & & \\ & 1 & -1 & & \\ & & -1 & & \\ & & \vdots & \ddots & \\ & & -1 & & 1 \end{pmatrix} \\\end{aligned}\]

对于第一部分
由于\(I_1\)仅有第\(9\)行有效
那么我们其实没必要将整个\(\{A_1\}\)存下来,仅需知道每个矩阵最后一行即可

当我们\(A\)左乘上\(M_c^{-1}\),观察会发生什么变化
\(i\)列整体减去\(A_{c,i}\)\(i\neq c\)
\(c\)列不发生变化
我们对矩阵\(A\)维护一个矩阵\(A'\),且每一列维护\(tag_i\),表示\(A_{i,j}=A'_{i,j}+tag_j\)
假设当前某一列为\(\begin{pmatrix}a_0+tag_i,a_1+tag_i,\cdots,a_c+tag_i,\cdots,a_{9}+tag_i\end{pmatrix}^T\)
那么其将变成:\(\begin{pmatrix}a_0-a_c,a_1-a_c,\cdots,a_c+tag_i,\cdots,a_{9}-a_c\end{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}(i\in[0,9])\),其修改为第\(i\)行之和;其他位置不变
那么每次\(A\)一行中只会有一个位置发生变化
我们在维护\(A\)的同时很容易预处理出列向量\(A'\)

时间复杂度\(O(10(n+q))\)

code

可能上面讲的有点绕,可以看下代码
code

posted @ 2020-12-26 18:49  Grice  阅读(111)  评论(0编辑  收藏  举报