题目描述
You are given four positive integers
x
0
,
x
1
,
a
,
b
x_0, x_1, a, b
x0,x1,a,b. And you know
x
i
=
a
⋅
x
i
−
1
+
b
⋅
x
i
−
2
x_i = a \cdot x_{i-1} + b \cdot x_{i-2}
xi=a⋅xi−1+b⋅xi−2 for all
i
≥
2
i \ge 2
i≥2.
Given two positive integers n, and MOD, please calculate x n x_n xn modulo MOD.
Does the problem look simple? Surprise! The value of n may have many many digits!
输入描述:
The input contains two lines.
The first line contains four integers
x
0
,
x
1
,
a
,
b
x_0, x_1, a, b
x0,x1,a,b
(
1
≤
x
0
,
x
1
,
a
,
b
≤
1
0
9
)
(1 \le x_0, x_1, a, b \le 10^9)
(1≤x0,x1,a,b≤109)
The second line contains two integers
n
n
n, MOD
(
1
≤
n
<
1
0
(
1
0
6
)
,
1
0
9
<
M
O
D
≤
2
×
1
0
9
,
n
h
a
s
n
o
l
e
a
d
i
n
g
z
e
r
o
)
(1 \le n < 10^{(10^6)}, 10^9 < MOD \le 2 \times 10^9 , n\ has\ no\ leading\ zero)
(1≤n<10(106),109<MOD≤2×109,n has no leading zero).
输出描述:
Print one integer representing the answer.
示例1
输入
1 1 1 1
10 1000000001
输出
89
说明
The resulting sequence x is Fibonacci sequence. The 11-th item is 89.
示例2
输入
1315 521 20185 5452831
9999999999999999999999999999999999999 1000000007
输出
914730061
题目大意:
已知公式
x
i
=
a
⋅
x
i
−
1
+
b
⋅
x
i
−
2
x_i=a \cdot x_{i-1} + b \cdot x_{i-2}
xi=a⋅xi−1+b⋅xi−2
第一行输入
x
0
,
x
1
,
a
,
b
x_0,x_1,a,b
x0,x1,a,b
第二行输入
n
,
p
n,p
n,p
求
x
n
%
p
x_n\%p
xn%p的值
解题思路:
由于此题
n
n
n的数据范围很大,而且又知道公式,所以可以很容易想到是矩阵快速幂的裸题,但由于
n
n
n的范围很大,所以需将二进制的快速幂写法改为十进制。
由于
x
i
=
a
⋅
x
i
−
1
+
b
⋅
x
i
−
2
x_i=a \cdot x_{i-1} + b \cdot x_{i-2}
xi=a⋅xi−1+b⋅xi−2
所以
∣
x
n
+
1
x
n
0
0
∣
=
∣
x
0
x
1
0
0
∣
∗
∣
a
1
b
0
∣
n
\begin{vmatrix} x_{n+1} & x_n \\ 0 & 0 \end{vmatrix}=\begin{vmatrix} x_0 & x_1 \\ 0 & 0 \end{vmatrix}*\begin{vmatrix} a & 1 \\ b & 0 \end{vmatrix}^n
∣∣∣∣xn+10xn0∣∣∣∣=∣∣∣∣x00x10∣∣∣∣∗∣∣∣∣ab10∣∣∣∣n
因此直接敲矩阵快速幂即可。
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <set>
#include <utility>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define inf 0x3f3f3f3f
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define lep(i,l,r) for(int i=l;i>=r;i--)
#define ms(arr) memset(arr,0,sizeof(arr))
//priority_queue<int,vector<int> ,greater<int> >q;
const int maxn = (int)1e5 + 5;
const ll mod = 1e9+7;
struct node
{
ll arr[2][2];
node() {
ms(arr);
}
};
ll p;
node mul(node a,node b) {
node c;
for(int i=0;i<2;i++) {
for(int j=0;j<2;j++) {
for(int k=0;k<2;k++) {
c.arr[i][j]=(c.arr[i][j]+(a.arr[i][k]*b.arr[k][j])%p)%p;
}
}
}
return c;
}
char str[1001000];
node b1,base;
int len;
ll quickpow() {
for(int i=len-1;i>=0;i--) {
int x=(int)(str[i]-'0');
node nape2;
nape2.arr[0][0]=base.arr[0][0];
nape2.arr[0][1]=base.arr[0][1];
nape2.arr[1][0]=base.arr[1][0];
nape2.arr[1][1]=base.arr[1][1];
while(x) {
if(x&1) b1=mul(b1,nape2);
nape2=mul(nape2,nape2);
x>>=1;
}
node nape1=mul(base,base);
base=mul(base,base);
base=mul(base,base);
base=mul(base,base);
base=mul(nape1,base);
}
return b1.arr[0][1]%p;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
//freopen("out.txt", "w", stdout);
//ios::sync_with_stdio(0),cin.tie(0);
ll x0,x1,a,b;
scanf("%I64d %I64d %I64d %I64d",&x0,&x1,&a,&b);
scanf("%s",str);
scanf("%I64d",&p);
base.arr[0][0]=a;base.arr[0][1]=1LL;
base.arr[1][0]=b;base.arr[1][1]=0;
b1.arr[0][0]=x1;b1.arr[0][1]=x0;
b1.arr[1][0]=0;b1.arr[1][1]=0;
len=strlen(str);
printf("%I64d\n",quickpow());
return 0;
}