You are given four positive integers x_0, x_1, a, bx0,x1,a,b. And you know x_i = a \cdot x_{i-1} + b \cdot x_{i-2}xi=a⋅xi−1+b⋅xi−2 for all i \ge 2i≥2.
Given two positive integers n, and MOD, please calculate x_nxn 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, bx0,x1,a,b (1 \le x_0, x_1, a, b \le 10^91≤x0,x1,a,b≤109).
The second line contains two integers n, MOD (1 \le n < 10^{(10^6)}, 10^9 < MOD \le 2 \times 10^91≤n<10(106),109
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
思路:拆成十进制快速幂+二进制快速幂,直接看代码就能懂。
#include
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
typedef long long ll;
//typedef vector vec;
//typedef vector mat;
const int MAXN = 1e6+50;
const int INF = 0x3f3f3f3f;
struct mat{
ll m[2][2];
mat(){memset(m, 0, sizeof(m));}
};
ll t, mod;
char n[MAXN];
mat mul(mat &A, mat &B){
mat C;
for(int i = 0; i < 2; i++){
for(int k = 0; k < 2; k++){
for(int j = 0; j < 2; j++){
C.m[i][j] = (C.m[i][j] + A.m[i][k] * B.m[k][j]) % mod;
}
}
}
return C;
}
mat pow2(mat A, int p){
mat B;
for(int i = 0; i < 2; i++)
B.m[i][i] = 1;
while(p){
if(p&1) B = mul(B, A);
A = mul(A, A);
p >>= 1;
}
return B;
}
mat pow10(mat A, char *p){
int l = strlen(p) - 1;
mat B;
for(int i = 0; i < 2; i++)
B.m[i][i] = 1;
per(i, l, 0){
if(p[i]-'0'>0){
B = mul(B, pow2(A, p[i]-'0'));
}
A = pow2(A, 10);
}
return B;
}
int main() {
//ios::sync_with_stdio(false);
ll x0, x1, a, b;
scanf("%lld%lld%lld%lld", &x0, &x1, &a, &b);
mat mm;
mm.m[0][0] = a; mm.m[0][1] = b;
mm.m[1][0] = 1; mm.m[1][1] = 0;
scanf("%s%lld", n, &mod);
mm = pow10(mm, n);
ll ans = ((x1*mm.m[1][0])%mod + (x0*mm.m[1][1])%mod)%mod;
printf("%lld\n", ans);
return 0;
}
/**/