题意简述
有序列 $S$,其中 $S_1=A,S_2=B;S_i=X\cdot S_{i-1}+Y\cdot S_{i-2}+Z(i>2)\% P$。
$Q$ 个询问求 $\sum\limits_{i=L}^{R}[S_i=C]$。
$A,B,X,Y,C,P,Q$ 均给定,$P$ 为不超过 $10007$ 的质数,$0\le A,B,X,Y,C<P$,$Q\le 2\times 10^4$,$1\le L\le R\le 10^{18}$。
主要思路
先把 $X=0$ 或 $Y=0$ 等情况判了。此时循环节长度 $O(P)$,暴力找出即可。
注意到此时可能循环节从 $3$ 开始。
设 $F_i=\begin{bmatrix}S_i\\S_{i+1}\\1\end{bmatrix},M=\begin{bmatrix}0&1&0\\Y&X&Z\\0&0&1\end{bmatrix}$,则有 $F_i = M\times F_{i-1}$。
不同的 $F_i$ 仅有 $P^2$ 个,由HDU 5451的经验,循环节一定是 $P^2-1$ 的约数,并且 $X>0,Y>0$ 时因为转移矩阵可逆,故一定是纯循环。
那么就先来找最小循环节 $R$。枚举约数矩阵快速幂即可。
然后考虑如何找到循环节中所有 $S_i=C$。由于循环节内相同 $F_i$ 只会出现一次,我们试图枚举 $m$,找到所有 $t=\begin{bmatrix}C\\m\\1\end{bmatrix}$ 的位置。
即,找到 $0\le k<R$ 使 $M^k F_1=t$ 成立。
设一阈值 $L$,则 $M^{dL-e}F_1=t$。由于 $M$ 可逆,变成 $M^{dL}F_1=M^et$,且 $d$ 是 $O({R\over L})$ 级别,$e$ 是 $O(L)$ 级别。
不难想到可以 $O({R\over L})$ 预处理出所有左边的可能值,扔到 Hash Table 里,就支持 $O(1)$ 查询。
那么每次查询时,枚举 $e$,即可做到 $O(L)$ 单次查询。喂这不就是 BSGS……
由于有 $O(P)$ 次查询(枚举 $m$),所以时间复杂度是 $O(LP)+O({R\over L})$,由于 $R$ 是 $O(P^2)$ 级别,故 $L$ 取 $\sqrt{P}$ 时复杂度最优为 $O(P\sqrt{P})$。
之后,每个询问就 $O(\log P)$ 了。
总时间复杂度 $O(P\sqrt{P} + Q\log P)$。
参考代码
代码真的很烦,我的 Hash Table 都是抄 Sunli Chen 的。
1 |
|
然后喜提最速解(