题目
描述
一个有自然数组成的数列按下式定义:
对于
i
<
=
k
:
A
i
=
B
i
i<=k:A_i=B_i
i<=k:Ai=Bi
对于
i
>
k
:
A
i
=
C
1
A
i
−
1
+
C
2
A
i
−
2
+
…
…
C
k
A
i
−
k
i>k:A_i=C_1A_{i-1}+C_2A_{i-2}+……C_kA_{i-k}
i>k:Ai=C1Ai−1+C2Ai−2+……CkAi−k
其中,
B
j
和
C
j
B_j和C_j
Bj和Cj
(
1
≤
j
≤
k
)
(1 \leq j \leq k)
(1≤j≤k)是给定的自然数。写一个程序,给定自然数
m
<
=
n
m<=n
m<=n,计算
A
m
+
A
m
+
1
+
…
…
A
n
A_m+A_{m+1}+……A_n
Am+Am+1+……An,并输出它除以给定自然数
p
p
p的余数的值。
输入
第一行是自然数
k
k
k
第二行包括
k
k
k个自然数
b
1
,
b
2
,
…
…
,
b
k
b_1,b_2,……,b_k
b1,b2,……,bk
第三行包含
k
k
k个自然数
c
1
,
c
2
,
…
…
,
c
k
c_1,c_2,……,c_k
c1,c2,……,ck
第四行包含三个自然数
m
,
n
,
p
m,n,p
m,n,p
输出
一个正整数,表示
(
A
m
+
A
m
+
1
+
…
…
A
n
)
%
p
(A_m+A_{m+1}+……A_n)\%p
(Am+Am+1+……An)%p的值
样例输入
2
1 1
1 1
2 10 10003
样例输出
142
思路
我们设
S
i
S_i
Si为
A
i
A_i
Ai的前缀和,那么此题不就是求
S
n
−
S
m
−
1
S_n-S_{m-1}
Sn−Sm−1吗,
所以初始矩阵就为
[
A
1
,
A
2
,
…
,
A
k
,
S
k
]
\begin{bmatrix} A_1,A_2,…,A_k,S_k\end{bmatrix}
[A1,A2,…,Ak,Sk]
而
A
k
+
1
=
C
1
A
k
+
C
2
A
k
−
1
+
…
…
C
k
A
1
A_{k+1}=C_1A_k+C_2A_{k-1}+……C_kA_{1}
Ak+1=C1Ak+C2Ak−1+……CkA1,而矩阵中有的如
A
1
A_1
A1要变成
A
2
A_2
A2,我们就把矩阵中的第一列的第二行记为一就行了,其他均如此,所以我们要乘的矩阵就为一个
k
+
1
k+1
k+1的方阵
k
+
1
个
[
0
,
0
,
…
,
0
,
C
k
,
C
k
1
,
0
,
…
,
0
,
C
k
−
1
,
C
k
−
1
0
,
1
,
…
,
0
,
C
k
−
2
,
C
k
−
2
⋮
0
,
0
,
…
,
1
,
C
2
,
C
2
0
,
0
,
…
,
0
,
C
1
,
C
1
]
⏞
\begin{matrix} k+1个\\ \overbrace{ \begin{bmatrix} 0,0,…,0,C_k,C_k \\ 1,0 ,…,0,C_{k-1},C_{k-1}\\ 0,1 ,…,0,C_{k-2},C_{k-2}\\ \vdots \\ 0,0,…,1,C_2,C_2\\ 0,0,…,0,C_1,C_1 \end{bmatrix} }\end{matrix}
k+1个⎣⎢⎢⎢⎢⎢⎢⎢⎡0,0,…,0,Ck,Ck1,0,…,0,Ck−1,Ck−10,1,…,0,Ck−2,Ck−2⋮0,0,…,1,C2,C20,0,…,0,C1,C1⎦⎥⎥⎥⎥⎥⎥⎥⎤
读者可以发现,左下角是一个长宽为
k
−
1
k-1
k−1的单位矩阵,自己搞吧
但要注意,当
n
,
m
≤
k
n,m\leq k
n,m≤k时,你就只有自己搞个循环加了
代码
我是倒着存的
[
A
k
,
…
,
A
2
,
A
1
,
S
k
]
\begin{bmatrix} A_k,…,A_2,A_1,S_k\end{bmatrix}
[Ak,…,A2,A1,Sk]
因此我乘的矩阵就为
k
+
1
个
[
C
1
,
1
,
…
0
,
C
1
C
2
,
0
,
1
…
0
,
C
2
C
3
,
0
,
0
,
1
…
0
,
C
3
⋮
C
k
−
2
,
0
,
0
…
,
1
,
C
k
−
2
C
k
−
1
,
0
,
0
…
,
0
,
C
k
−
1
C
k
,
0
,
0
…
,
0
,
C
k
]
⏞
\begin{matrix} k+1个\\ \overbrace{ \begin{bmatrix} C_1,1,…0,C_1 \\ C_2,0,1…0,C_2\\ C_3,0,0,1…0,C_3\\ \vdots \\ C_{k-2},0,0…,1,C_{k-2}\\ C_{k-1},0,0…,0,C_{k-1}\\ C_k,0,0…,0,C_k \end{bmatrix} }\end{matrix}
k+1个⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡C1,1,…0,C1C2,0,1…0,C2C3,0,0,1…0,C3⋮Ck−2,0,0…,1,Ck−2Ck−1,0,0…,0,Ck−1Ck,0,0…,0,Ck⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
中间是一个
k
−
1
k-1
k−1的单位矩阵
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define LL long long
LL n, m, k, ans, p;
struct Mx{
int x, y;
LL a[18][18];
inline void cl(){
memset(a, 0, sizeof(a));
}
Mx operator * (const Mx &b)const{
Mx r;
for(int i = 1; i <= x; i ++){
for(int j = 1; j <= b.y; j ++){
r.a[i][j] = 0;
for(int k = 1; k <= b.x; k ++)
r.a[i][j] = (r.a[i][j]+b.a[k][j]*a[i][k]%p)%p;
}
}
r.x = x;
r.y = b.y;
return r;
}
void print(){
for(int i = 1; i <= x; i ++){
for(int j = 1; j <= y; j ++)
printf("%lld ", a[i][j]);
printf("\n");
}
}
}A, one, F, M, N;
inline Mx qkp(Mx x, LL y){
Mx sum = one;
while( y ){
if( y&1 )
sum = x * sum;
x = x * x;
y >>= 1;
}
return sum;
}
int main(){
scanf("%lld", &k);
A.cl();
one.cl();
F.cl();
LL sum = 0;
one.x = one.y = k+1;
A.x = 1, A.y = k+1;
for(int i = 1; i <= k; i ++){
scanf("%lld", &A.a[1][k-i+1]);
one.a[i][i] = 1;
sum += A.a[1][k-i+1];
}
one.a[k+1][k+1] = 1;
A.a[1][k+1] = sum;
F.x = F.y = k+1;
for(int i = 1; i <= k; i ++){
scanf("%lld", &F.a[i][1]);
F.a[i][k+1] = F.a[i][1];
}
for(int i = 1; i <= k; i ++){
if( !F.a[i][i+1] )
F.a[i][i+1] = 1;
}
F.a[k+1][k+1] = 1;
scanf("%lld%lld%lld", &m,&n,&p);
if( n >= k ){
N = A * qkp(F, 1ll*(n-k));
ans = (ans + N.a[1][k+1])%p;
}
else{
for(int i = 1; i <= n; i ++)
ans = (ans+A.a[1][k-i+1])%p;
}
if( m > k+1 ){
M = A * qkp(F, m-k-1);
ans = (ans-M.a[1][k+1]+p)%p;
}
else{
for(int i = 1; i < m; i ++)
ans = ( ans - A.a[1][k-i+1] + p ) %p;
}
printf("%lld\n", (ans+p)%p);
return 0;
}