タイトルの説明
4つの正の整数が与えられます。そして、あなたはすべてのために知っています。
2つの正の整数nとMODが与えられた場合、MODを法として計算してください。
問題は単純に見えますか?驚き!nの値には多くの桁が含まれる場合があります。
説明を入力してください
入力には2行が含まれます。
最初の行には4つの整数()が含まれています 。
2行目には、2つの整数n MOD(、nには先行ゼロはありません)が含まれています。
出力の説明
答えを表す1つの整数を出力します。
入力例1
1 1 1 1
10 1000000001
出力例1
89
解説
結果のシーケンスxはフィボナッチ数列です。11番目のアイテムは89です。
入力例2
1315 521 20185 5452831
9999999999999999999999999999999999999 1000000007
出力例2
914730061
主なアイデア:
開始項と再帰式を考えると、n番目の項MODの値が必要です。
分析:
開始項と再帰的な式があります。行列の高速指数を考えるのは簡単ですが、nは非常に大きくなります。バイナリマトリックスの高速指数を使用すると、確実にタイムアウトになり、10進数を考慮すれば、複雑さは問題ありません。
具体的な説明については、コードを参照してください。
#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;
}