https://ac.nowcoder.com/acm/contest/885/B
题意:
就是求第N项,N等于(10^(10^6))还得取模
题解:
- 推公式
- 处理公式:因为N指数特别大,所以需要这样处理,看下图,在字符串模拟十进制的时候按位进行十进制预处理快速幂
A^123=(A^120)*(A^3)
- 那么这个的复杂度显然为:O(len∗log2(10)∗n3)O(len∗log2(10)∗n3)
- 其中n为矩阵大小,len为字符串长度,log10为快速幂的操作。
细节就是,Xn最后等于常数矩阵的(N-1)次幂,但因为N太大,按字符串存,不好去-1,所以最后直接算的是Xn的第N次幂,
用Xn-1=(Xn-1)*1+(Xn-2)*0来表示
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e6 + 5;
const int INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;
ll mod;
struct Matrix{
ll m[2][2];
}num[20];
Matrix Mul(Matrix a, Matrix b){
Matrix c;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
c.m[i][j]=0;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++){
for(int k=0;k<2;k++)
c.m[i][j]+=(a.m[i][k]*b.m[k][j])%mod;
c.m[i][j]=c.m[i][j]%mod;
}
return c;
}
Matrix pow(Matrix rec,int x){
Matrix ans;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++){
if(i==j)
ans.m[i][j]=1;
else
ans.m[i][j]=0;
}
while(x){
if(x%2)
ans=Mul(ans,rec);
rec=Mul(rec,rec);
x=x/2;
}
return ans;
}
int main(){
int x0,x1,a,b;
cin>>x0>>x1>>a>>b;
string n;
cin>>n;
int len=n.size();
cin>>mod;
Matrix a1;//单位矩阵
a1.m[0][0]=1;a1.m[0][1]=0;
a1.m[1][0]=0;a1.m[1][1]=1;
Matrix tmp;
tmp.m[0][0]=a;tmp.m[0][1]=b;
tmp.m[1][0]=1;tmp.m[1][1]=0;
num[0]=a1;
for(int i=1;i<=9;i++){//预处理
num[i]=Mul(num[i-1],tmp);
}
for(int i=0;i<len;i++){
a1=pow(a1,10);
int k=n[i]-'0';
a1=Mul(a1,num[k]);
}
cout<<(a1.m[1][0]*x1+a1.m[1][1]*x0)%mod;
return 0;
}