题目描述
You are given four positive integers . And you know for all .
Given two positive integers n, and MOD, please calculate 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 ().
The second line contains two integers n, MOD (, n has no leading zero).
输出描述
Print one integer representing the answer.
示例输入1
1 1 1 1
10 1000000001
示例输出1
89
说明
The resulting sequence x is Fibonacci sequence. The 11-th item is 89.
示例输入2
1315 521 20185 5452831
9999999999999999999999999999999999999 1000000007
示例输出2
914730061
题目大意:
给出起始项和递推公式,要求出第n项模MOD的值。
分析:
有起始项又有递推公式,很容易想到矩阵快速幂,但是这里的n很大,如果用二进制的矩阵快速幂肯定超时,而如果考虑十进制的话, 的复杂度是可以的。
具体解释见代码。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
#define ll long long
#define INF 0x3f3f3f3f
#define N 2
using namespace std;
const int maxn=1000005;
ll mod;
char str[maxn];
struct mat{
ll m[N+1][N+1];
};
mat mul(mat a,mat b){
mat ans;
int i,j,k;
for(i=1;i<=N;i++)
for(j=1;j<=N;j++)
ans.m[i][j]=0;
for(i=1;i<=N;i++)
for(j=1;j<=N;j++)
for(k=1;k<=N;k++)
ans.m[i][j]=(ans.m[i][j]+a.m[i][k]*b.m[k][j]+mod)%mod;
return ans;
}
mat matqp(ll p,mat t){//二进制矩阵快速幂,此题不可用
mat ans;
int i,j;
for(i=1;i<=N;i++)
for(j=1;j<=N;j++)
if(i==j)ans.m[i][j]=1;
else ans.m[i][j]=0;
while(p)
{
if(p&1)
ans=mul(ans,t);
t=mul(t,t);
p=p>>1;
}
return ans;
}
mat dmatqp(char* n,mat a){//十进制矩阵快速幂(类比二进制写)
mat ans;
int i,j;
for(i=1;i<=N;i++)
for(j=1;j<=N;j++)
if(i==j)ans.m[i][j]=1;
else ans.m[i][j]=0;
int len=strlen(n);
for(i=len-1;i>=0;i--){
int num=n[i]-'0';
for(j=1;j<=num;j++) ans=mul(ans,a);//这里处理的是每一位的系数
mat tmp=a;
for(j=1;j<=9;j++) a=mul(a,tmp);//这里计算下一位的基数
}
return ans;
}
int main(){
ll x0,x1,a,b;
scanf("%lld%lld%lld%lld",&x0,&x1,&a,&b);
scanf("%s",str);
scanf("%lld",&mod);
int len=strlen(str);
int l=len-1;
while(l>=0){//这里将str数组中代表的整数减一
if(str[l]=='0'){
str[l]='9';
l--;
continue;
}
else{
str[l]--;
break;
}
}
//构造初始矩阵
mat mt;
mt.m[1][1]=a;
mt.m[1][2]=b;
mt.m[2][1]=1;
mt.m[2][2]=0;
mat res=dmatqp(str,mt);
ll answ=((res.m[1][1]*x1+mod)%mod+(res.m[1][2]*x0+mod)%mod)%mod;
printf("%lld\n",answ%mod);
return 0;
}