链接:https://ac.nowcoder.com/acm/contest/885/B
来源:牛客网
You are given four positive integers x0,x1,a,b. And you know xi=a⋅xi−1+b⋅xi−2 for all i≥2 .
Given two positive integers n, and MOD, please calculate xnx_nxn modulo MOD.
Does the problem look simple? Surprise! The value of n may have many many digits!
题意:
很简单,给你有关xi的递推公式和a,b,x0,x1,求出xn
输入描述:
The input contains two lines.
The first line contains four integers x0,x1,a,b (1≤x0,x1,a,b≤10^9).
The second line contains two integers n, MOD (1≤n<10^(10^6),10^9<MOD≤2×10^9, 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
思路:
一看到xi=a⋅xi−1+b⋅xi−2,并且给你初值,求xn,马上就想到了矩阵快速幂,但是快速幂以2为单位,n<10^(10^6),long long 都读不进n,赛后看题解和别人代码,豁然开朗,快速幂以10为单位,n用字符串存储,可以方便得解决这题。以10为单位解法具体看代码
求快速幂用的矩阵
PS:虽然(x0,x1)是1*2的矩阵,但是为了方便与2*2的A相乘,(x0,x1)也设置为2*2的矩阵((x0,x1),(0,0))
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX=2e9;
ll x0,x1,a,b,mod;
string n;
struct matrix{
ll a[2][2];
void init0() { a[0][0]=a[0][1]=a[1][0]=a[1][1]=0; }
void init1() { a[0][1]=a[1][0]=0; a[0][0]=a[1][1]=1; }//初始化为单位矩阵
void init(int x0,int y0,int x1,int y1){
a[0][0]=x0; a[0][1]=y0; a[1][0]=x1; a[1][1]=y1;
}
matrix operator * (const matrix& b) {
matrix res; res.init0();
res.a[0][0] = (a[0][0] * b.a[0][0] + a[0][1] * b.a[1][0]) % mod ;
res.a[0][1] = (a[0][0] * b.a[0][1] + a[0][1] * b.a[1][1]) % mod ;
res.a[1][0] = (a[1][0] * b.a[0][0] + a[1][1] * b.a[1][0]) % mod ;
res.a[1][1] = (a[1][0] * b.a[0][1] + a[1][1] * b.a[1][1]) % mod ;
return res;
}
};
matrix ten(matrix A){
matrix t2 = A * A;//A的平方
matrix t4 = t2 * t2;//四次
matrix t8 = t4 * t4;//8次
return t8 * t2 ; //返回10次
}
matrix pow(matrix A,string& n){//矩阵快速幂,以10为单位
matrix res; res.init1();
for(int i=n.length()-1;i>=0;i--){
int num=n[i]-'0';
while(num--) res = res * A; //res*num个A
A = ten(A); //下一位的数,每一个就是以A^10为单位
}
return res;
}
int main()
{
cin>>x0>>x1>>a>>b>>n>>mod;
matrix xx,y;
xx.init(x0,x1,0,0); y.init(0,b,1,a);
y = pow(y,n);
xx = xx * y;
printf("%lld\n",xx.a[0][0]);
return 0;
}