题目描述
You are given four positive integers x0,x1,a,bx_0, x_1, a, bx0,x1,a,b. And you know xi=a⋅xi−1+b⋅xi−2x_i = a \cdot x_{i-1} + b \cdot x_{i-2}xi=a⋅xi−1+b⋅xi−2 for all i≥2i \ge 2i≥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!
输入描述:
The input contains two lines.
The first line contains four integers x0,x1,a,bx_0, x_1, a, bx0,x1,a,b (1≤x0,x1,a,b≤109)(1 \le x_0, x_1, a, b \le 10^9)(1≤x0,x1,a,b≤109)
The second line contains two integers nnn, MOD (1≤n<10(106),109<MOD≤2×109,nhasnoleadingzero)(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
题目大意:
已知公式xi=a⋅xi−1+b⋅xi−2x_i=a \cdot x_{i-1} + b \cdot x_{i-2}xi=a⋅xi−1+b⋅xi−2
第一行输入x0,x1,a,bx_0,x_1,a,bx0,x1,a,b
第二行输入n,pn,pn,p
求xn%px_n\%pxn%p的值
解题思路:
由于此题nnn的数据范围很大,而且又知道公式,所以可以很容易想到是矩阵快速幂的裸题,但由于nnn的范围很大,所以需将二进制的快速幂写法改为十进制。
由于xi=a⋅xi−1+b⋅xi−2x_i=a \cdot x_{i-1} + b \cdot x_{i-2}xi=a⋅xi−1+b⋅xi−2
所以
∣xn+1xn00∣=∣x0x100∣∗∣a1b0∣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_JUDGEfreopen("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;
}