问题描述 Description
现定义序列它的第 i i i项为: F i = S i − 1 ∗ F i − 1 + S i − 2 ∗ F i − 2 F_i=S_{i-1}*F_{i-1}+S_{i-2}*F_{i-2} Fi=Si−1∗Fi−1+Si−2∗Fi−2 定义 F 0 = 0 F_0=0 F0=0以及 F 1 = 1 F_1=1 F1=1
其中, S S S是一个无限长的,几乎循环的一个数字序列,它的循环节长度为 N N N,也就是说,通常会有 S i = S i m o d N S_i=S_{i\bmod N} Si=SimodN。但是 S S S中也存在少数元素并不符合这个循环节,也就是说,会有若干个元素, S i ≠ S i m o d N S_i\not=S_{i\bmod N} Si=SimodN。
现在给出序列 S S S的循环节,以及 S S S中不符合循环的位置以及值,求 F k m o d P F_k\bmod P FkmodP。
输入 Input
输入文件的第一行有两个整数 K K K和 P P P。
第二行是一个整数 N N N。
第三行包含 N N N个正整数,表示循环节中所有的数字。
接下来一行是一个整数 M M M。接下来的 M M M行,每行包含两个整数 x x x和 y y y,表示在序列 S S S中不符合循环节的位置以及相应位置上的值,即 S x = y S_x=y Sx=y。
输出 Output
输出文件包含一个整数,即相应输入文件的答案。
样例输入 Sample Input
42 1248493
5
5 2 4 1 6
5
9 3
8 4
21 21
10 18
24 10
样例输出 Sample Output
232959
限制 Limits
对于30%的数据: 0 ≤ k ≤ 10000 , 1 ≤ n ≤ 1000 , 1 ≤ M ≤ 20 0\le k\le 10000,1\le n\le 1000,1\le M\le 20 0≤k≤10000,1≤n≤1000,1≤M≤20;
对于70%的数据: 0 ≤ k ≤ 1 0 18 , 1 ≤ n ≤ 1000 , 1 ≤ M ≤ 20 0\le k\le 10^{18},1\le n\le 1000,1\le M\le 20 0≤k≤1018,1≤n≤1000,1≤M≤20;
对于100%的数据: 0 ≤ k ≤ 1 0 18 , 1 ≤ n , m ≤ 5 × 1 0 4 , 1 ≤ p ≤ 1 0 9 , 1 ≤ S i ≤ 1 0 9 , n ≤ x ≤ 1 0 18 , 1 ≤ y ≤ 1 0 9 0\le k\le 10^{18},1\le n,m\le 5\times 10^4,1\le p\le 10^9,1\le S_i\le 10^9,n\le x\le 10^{18},1\le y\le 10^9 0≤k≤1018,1≤n,m≤5×104,1≤p≤109,1≤Si≤109,n≤x≤1018,1≤y≤109 。
Time Limit : 2 s 2s 2s & Memory Limit : 128 M B 128MB 128MB
一看
k
k
k这么大快速幂逃不掉了…
一看递推关系矩阵逃不掉了…
所以矩阵快速幂逃不掉了。
MDZZ怎么搞矩阵?
这回在化学课上推公式…
f
0
=
0
f
1
=
1
f
2
=
s
1
f
1
=
s
1
f
3
=
s
2
f
2
+
s
1
f
1
=
s
1
s
2
+
s
1
f
4
=
s
3
f
3
+
s
2
f
2
=
s
1
s
2
s
3
+
s
1
s
2
+
s
1
s
3
…
\begin{aligned} f_0&=0\\ f_1&=1\\ f_2&=s_1f_1=s_1\\ f_3&=s_2f_2+s_1f_1=s_1s_2+s_1\\ f_4&=s_3f_3+s_2f_2=s_1s_2s_3+s_1s_2+s_1s_3\\ &\dots \end{aligned}
f0f1f2f3f4=0=1=s1f1=s1=s2f2+s1f1=s1s2+s1=s3f3+s2f2=s1s2s3+s1s2+s1s3…
看出什么来了吗?
反正我看了一天
可以看出这个
f
f
f只与
s
s
s有关…
假如能搞出一个矩阵的话,可以借鉴分块思想,将一个循环节看成一个块,将整个块内的值求出后,跑矩阵快速幂,之后零散部分暴力。
可是有修改…
就将修改看成断点,假如断点处于同一块内,暴力即可,如果不在,零散暴力,整块快速幂。
时间为
O
(
m
n
log
2
k
)
O(mn\log_2 k)
O(mnlog2k)
这样可以过
70
%
70\%
70%…
100
%
100\%
100%优化的是零散部分,因为要不停计算零散部分,这些零散部分还是循环的,所以可以用线段树优化。
时间为
O
(
m
log
2
n
log
2
k
)
O(m\log_2 n\log_2 k)
O(mlog2nlog2k)
所以,怎么构造矩阵?
还是两个矩阵,一个是处理影响的,一个是统计答案的。
统计答案的矩阵是一个
1
×
2
1\times2
1×2的矩阵:
[
f
a
+
1
f
a
]
\begin{bmatrix} f_{a+1}& f_a \end{bmatrix}
[fa+1fa]
当然也可以写成
2
×
2
2\times2
2×2的,其余补
0
0
0即可。
处理影响的矩阵是一个
2
×
2
2\times2
2×2的矩阵:
[
0
s
a
1
s
a
+
1
]
\begin{bmatrix} 0 & s_{a}\\ 1 & s_{a+1} \end{bmatrix}
[01sasa+1]
遇到断点答案矩阵暴力乘矩阵即可,此矩阵为:
[
0
s
x
−
1
1
c
]
\begin{bmatrix} 0&s_{x-1}\\ 1&c \end{bmatrix}
[01sx−1c]
其中
x
x
x为需要修改的位置,
c
c
c为变换成的数。
这还没完,因为矩阵与
x
+
1
x+1
x+1位置也有关,还需要乘:
[
0
c
1
s
x
+
1
]
\begin{bmatrix} 0&c\\ 1&s_{x+1} \end{bmatrix}
[01csx+1]
这样就可以了
还有一些许多细节需要注意…具体参见代码。
Code