题目大意
转送门
让你求一个数列的第n个数
思路
我们设
f
[
n
]
=
a
[
n
]
×
b
[
n
]
f[n]=a[n]\times b[n]
f[n]=a[n]×b[n],而
A
o
b
[
n
]
=
∑
i
=
0
n
−
1
a
[
i
]
×
b
[
i
]
Aob[n]=\sum_{i=0}^{n-1}a[i]\times b[i]
Aob[n]=∑i=0n−1a[i]×b[i],所以
A
o
b
[
n
]
=
A
o
b
[
n
−
1
]
+
f
[
n
−
1
]
Aob[n]=Aob[n-1]+f[n-1]
Aob[n]=Aob[n−1]+f[n−1],而
f
[
n
−
1
]
=
a
[
n
]
×
b
[
n
]
f[n-1]=a[n]\times b[n]
f[n−1]=a[n]×b[n],
a
[
n
]
=
a
[
n
−
1
]
×
A
X
+
A
Y
a[n]=a[n-1]\times AX + AY
a[n]=a[n−1]×AX+AY,
b
[
n
]
=
b
[
n
−
1
]
×
B
X
+
B
Y
b[n]=b[n-1]\times BX + BY
b[n]=b[n−1]×BX+BY,所以
f
[
n
−
1
]
=
(
a
[
n
−
2
]
×
A
X
+
A
Y
)
×
(
b
[
n
−
2
]
∗
B
X
+
B
Y
)
=
A
X
×
B
X
×
a
[
n
−
2
]
×
b
[
n
−
2
]
+
b
[
n
−
2
]
×
B
X
×
A
Y
+
a
[
n
−
2
]
×
A
X
×
B
Y
+
A
Y
×
B
Y
=
A
X
∗
B
X
∗
f
[
n
−
2
]
+
b
[
n
−
2
]
×
B
X
×
A
Y
+
a
[
n
−
2
]
×
A
X
×
B
Y
+
A
Y
×
B
Y
f[n-1]=(a[n-2]\times AX+AY)\times (b[n-2]*BX+BY)=AX\times BX\times a[n-2]\times b[n-2]+b[n-2]\times BX\times AY+a[n-2]\times AX\times BY+AY\times BY=AX*BX*f[n-2]+b[n-2]\times BX\times AY + a[n-2]\times AX\times BY + AY\times BY
f[n−1]=(a[n−2]×AX+AY)×(b[n−2]∗BX+BY)=AX×BX×a[n−2]×b[n−2]+b[n−2]×BX×AY+a[n−2]×AX×BY+AY×BY=AX∗BX∗f[n−2]+b[n−2]×BX×AY+a[n−2]×AX×BY+AY×BY,所以,我们
f
[
n
]
f[n]
f[n]就可以通过
f
[
n
−
1
]
f[n-1]
f[n−1]转移过来,所以
A
o
b
[
n
]
Aob[n]
Aob[n]也可以通过
A
o
b
[
n
−
1
]
Aob[n-1]
Aob[n−1]转移过来,我们也可以利用矩阵加速了。因为我比较菜,所以,我构造了一个7个数的初始矩阵,
7
×
7
7\times 7
7×7的转移矩阵,长成这个样子:
既然初始矩阵都有了,那我就不给出转移矩阵了吧因为我懒得画,代码里面也有。然后,我们就可以成功地
O
(
7
3
l
o
g
n
)
O(7^3logn)
O(73logn)解决了,诶?怎么超时了?操要特判
n
=
0
n=0
n=0的情况,好吧,好像……,好像就没有什么了
代码
#pragma GCC optimize (2)
#include <set>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define Int register int
#define mod 1000000007
#define int long long
#define MAXN 10
struct Matrix
{
int n,m;
int a[MAXN][MAXN];
Matrix(){memset (a,0,sizeof (a));}
Matrix operator * (const Matrix &p)const
{
Matrix New;
New.n = n,New.m = p.m;
for (Int i = 1;i <= New.n;++ i)
for (Int j = 1;j <= New.m;++ j)
for (Int k = 1;k <= m;++ k)
New.a[i][j] = (New.a[i][j] + a[i][k] % mod * p.a[k][j] % mod) % mod;
return New;
}
};
Matrix quick_pow (Matrix a,int b)
{
Matrix res;
res.n = res.m = a.n;
for (Int i = 1;i <= res.n;++ i) res.a[i][i] = 1;
while (b)
{
if (b & 1)
res = res * a;
a = a * a;
b >>= 1;
}
return res;
}
void read (int &x)
{
x = 0;char c = getchar();int f = 1;
while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}
while (c >= '0' && c <= '9'){x = (x << 3) + (x << 1) + c - '0';c = getchar();}
x *= f;return ;
}
void write (int x)
{
if (x < 0){x = -x;putchar ('-');}
if (x > 9) write (x / 10);
putchar (x % 10 + '0');
}
signed main()
{
int N;
while (~scanf ("%lld",&N))
{
int A0,Ax,Ay,B0,Bx,By;
read (A0),read (Ax),read (Ay),read (B0),read (Bx),read (By);
A0 %= mod,Ax %= mod,Ay %= mod,B0 %= mod,Bx %= mod,By %= mod;
if (N == 0)
{
write (0),putchar ('\n');
continue;
}
if (N == 1)
{
write (A0 % mod * B0 % mod),putchar ('\n');
continue;
}
Matrix A,B,C;
A.n = 7,A.m = 1;
int A1 = A0 % mod * Ax % mod + Ay % mod,B1 = B0 % mod * Bx % mod + By % mod;
A1 %= mod,B1 %= mod;
A.a[1][1] = A0 % mod * B0 % mod,A.a[2][1] = A1 % mod * B1 % mod,A.a[3][1] = A1 % mod,A.a[4][1] = B1 % mod,
A.a[5][1] = Ay % mod * By % mod,A.a[6][1] = Ay % mod,A.a[7][1] = By % mod;
B.n = 7,B.m = 7;
B.a[1][1] = B.a[1][2] = B.a[2][5] = B.a[3][6] = B.a[4][7] = B.a[5][5] = B.a[6][6] = B.a[7][7] = 1;
B.a[2][2] = Ax % mod * Bx % mod,B.a[2][3] = Ax % mod * By % mod,B.a[2][4] = Ay % mod * Bx % mod;
B.a[3][3] = Ax % mod,B.a[4][4] = Bx % mod;
C = quick_pow (B,N - 1) * A;
write (C.a[1][1]),putchar ('\n');
}
return 0;
}