思路:把f(n)展开有
f
(
n
)
=
a
0
b
n
+
a
1
b
n
−
1
+
a
2
b
n
−
2
+
⋯
+
a
n
b
0
f\left ( n \right )=a_{0}b_{n}+a_{1}b_{n-1}+a_{2}b_{n-2}+\cdots +a_{n}b_{0}
f(n)=a0bn+a1bn−1+a2bn−2+⋯+anb0
再写出n-1
f ( n − 1 ) = a 0 b n − 1 + a 1 b n − 2 + a 2 b n − 3 + ⋯ + a n − 1 b 0 f\left ( n-1 \right )=a_{0}b_{n-1}+a_{1}b_{n-2}+a_{2}b_{n-3}+\cdots +a_{n-1}b_{0} f(n−1)=a0bn−1+a1bn−2+a2bn−3+⋯+an−1b0
我们让f(n-1)*q得到
f ( n − 1 ) q = a 0 b n + a 1 b n − 1 + a 2 b n − 2 + ⋯ + a n − 1 b 1 f\left ( n-1 \right )q=a_{0}b_{n}+a_{1}b_{n-1}+a_{2}b_{n-2}+\cdots +a_{n-1}b_{1} f(n−1)q=a0bn+a1bn−1+a2bn−2+⋯+an−1b1
发现与f(n)项相差了 a n b 0 a_{n}b_{0} anb0所以有
f ( n ) = f ( n − 1 ) q + a n b 0 f\left ( n \right )=f\left ( n-1 \right )q+a_{n}b_{0} f(n)=f(n−1)q+anb0
a n = a n − 1 p + r a_{n}=a_{n-1}p+r an=an−1p+r所以有
f ( n ) = f ( n − 1 ) q + a n − 1 p b 0 + r b 0 f\left ( n \right )=f\left ( n-1 \right )q+a_{n-1}pb_{0}+rb_{0} f(n)=f(n−1)q+an−1pb0+rb0
得到递推公式我们就可以写出矩阵了
有
(
f
(
n
)
a
n
r
)
=
(
q
p
b
0
b
0
0
p
1
0
0
1
)
(
f
(
n
−
1
)
a
n
−
1
r
)
\begin{pmatrix} f(n)\\ a_{n}\\ r \end{pmatrix}=\begin{pmatrix} q &pb_{0} &b_{0} \\ 0 &p &1 \\ 0 & 0 &1 \end{pmatrix}\begin{pmatrix} f(n-1)\\ a_{n-1}\\ r \end{pmatrix}
⎝⎛f(n)anr⎠⎞=⎝⎛q00pb0p0b011⎠⎞⎝⎛f(n−1)an−1r⎠⎞
递推就是
(
f
(
n
)
a
n
r
)
=
(
q
p
b
0
b
0
0
p
1
0
0
1
)
n
−
1
(
f
(
1
)
a
1
r
)
\begin{pmatrix} f(n)\\ a_{n}\\ r \end{pmatrix}=\begin{pmatrix} q &pb_{0} &b_{0} \\ 0 &p &1 \\ 0 & 0 &1 \end{pmatrix}^{n-1}\begin{pmatrix} f(1)\\ a_{1}\\ r \end{pmatrix}
⎝⎛f(n)anr⎠⎞=⎝⎛q00pb0p0b011⎠⎞n−1⎝⎛f(1)a1r⎠⎞
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 3
#define mod 1000000007
using namespace std;
typedef struct {
long long m[MAX][MAX];
}Matrix;
Matrix P={0};
Matrix I={1,0,0,0,1,0,0,0,1};
Matrix Matrixmul(Matrix a,Matrix b)
{
int i,j,k;
Matrix c;
for(i=0;i<MAX;i++)
for(j=0;j<MAX;j++)
{
c.m[i][j]=0;
for(k=0;k<MAX;k++)
{
c.m[i][j]+=(a.m[i][k]*b.m[k][j])%mod;
}
c.m[i][j]%=mod;
}
return c;
}
Matrix quickpow(long long n)
{
Matrix m=P,b=I;
while(n>0)
{
if(n%2==1)
b=Matrixmul(b,m);
n=n/2;
m=Matrixmul(m,m);
}
return b;
}
int main()
{
long long p,q,r,n;
while(scanf("%lld%lld%lld%lld",&p,&q,&r,&n)!=EOF)
{
P.m[0][0]=q;
P.m[0][1]=3*p;
P.m[0][2]=3;
P.m[1][1]=p;
P.m[1][2]=1;
P.m[2][2]=1;
Matrix a;
a=quickpow(n-1);
printf("%lld\n",(a.m[0][0]*3*r%mod+(a.m[0][1]+a.m[0][2])*r%mod)%mod);
}
return 0;
}