题目:https://ac.nowcoder.com/acm/contest/885/B
题意:求广义斐波那契的第n项,n的位数有1e6位
思路:将n保存成字符串。按十进制从后向前一位一位算即可。
代码:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 1e6+6;
struct Matrix{
LL m[2][2];
}E, O, base;
LL mod, x0, x1, a, b;
char n[maxn];
void init(){
memset(E.m, 0, sizeof E.m);
memset(O.m, 0, sizeof O.m);
memset(base.m, 0, sizeof base.m);
for(int i=0; i<2; i++) E.m[i][i] = 1;
}
Matrix mul(Matrix A, Matrix B){
Matrix res = O;
for(int i=0; i<2; i++)
for(int j=0; j<2; j++){
for(int k=0; k<2; k++){
res.m[i][j] += (A.m[i][k]*B.m[k][j])%mod;
if(res.m[i][j] > mod) res.m[i][j] -= mod;
}
}
return res;
}
Matrix Pow(Matrix A, int k){
Matrix res = E;
while(k){
if(k&1) res = mul(res, A);
A = mul(A, A);
k >>= 1;
}
return res;
}
void print(Matrix A){
for(int i=0; i<2; i++) {
for(int j=0; j<2; j++) cout << A.m[i][j] << " ";
cout << endl;
}cout << endl;
}
int main()
{
init();
scanf("%lld%lld%lld%lld", &x0, &x1, &a, &b);
base.m[0][0] = a; base.m[0][1] = 1; base.m[1][0] = b; base.m[1][1] = 0;
scanf("%s%lld", n, &mod);
int len = strlen(n);
Matrix A = Pow(base, int(n[len-1]-'0'));
Matrix B = base;
for(int i=len-2; i>=0; i--){
B = Pow(B, 10);
A = mul(A, Pow(B, int(n[i]-'0')));
}
printf("%lld\n", ((x1*A.m[0][1])%mod + (x0*A.m[1][1])%mod)%mod);
}