根据牛客多校所写:https://ac.nowcoder.com/acm/contest/885/B
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1000100;
const int NUM=2;//当前矩阵是几行几列的
ll MOD;//取模
char s[maxn];
struct Matrix {
ll a[NUM][NUM];
Matrix() {
memset(a,0,sizeof(a));
}
Matrix operator*(const Matrix y) {
Matrix ans;
for(int i=0; i<NUM; i++)
for(int j=0; j<NUM; j++)
for(int k=0; k<NUM; k++)
ans.a[i][j]=(ans.a[i][j]+(a[i][k]*y.a[k][j])%MOD+MOD)%MOD;
//有时候+MOD会出现段错误、超时等问题,很玄学,视具体情况而定
return ans;
}
/*void operator=(const Matrix b) {
for(int i=0; i<NUM; i++)
for(int j=0; j<NUM; j++)
a[i][j]=b.a[i][j];
}*///重载 = ,应该是不用重载也可以,但好像某些题目会卡,还是玄学问题,必要时加上
//重载之后,时间会增加,但某些玄学题目会过
};
Matrix mat_pow(Matrix c, ll n) {
Matrix res;
for(int i=0;i<NUM;i++){
for(int j=0;j<NUM;j++){
if(i==j) res.a[i][j]=1;
else res.a[i][j]=0;
}
}
while(n) {
if(n&1) res=res*c;
c=c*c;
n=n>>1;
}
//return res.a[0][0]; //根据实际需要二选一
return res;
}
Matrix qpow10(Matrix c,char *s){
int len=strlen(s)-1;
Matrix res;
for(int i=0;i<NUM;i++){
for(int j=0;j<NUM;j++){
if(i==j) res.a[i][j]=1;
else res.a[i][j]=0;
}
}
for(int i=len;i>=0;i--){
if(s[i]-'0'>0){
Matrix E;
E=(mat_pow(c,s[i]-'0'));
res=res*E;
}
c=mat_pow(c,10);
}
return res;
}
int main() {
// a b 两个矩阵,该模板可以快速求出 a^n * b 的结果,倘若n过大,我们还可以用字符串
//将其读入,用上面的pow10函数对其进行处理
// 根据题目的要求,更改上述NUM和MOD的值
ll x0,x1,a,b;
scanf("%lld%lld%lld%lld%s%lld",&x0,&x1,&a,&b,s,&MOD);//这里输入题目中要求的数值
Matrix mat;
mat.a[0][0]=a;mat.a[0][1]=b;mat.a[1][0]=1;mat.a[1][1]=0;
//初始矩阵赋值
mat=qpow10(mat,s);
ll ans=((x1*mat.a[1][0])%MOD+(x0*mat.a[1][1])%MOD)%MOD;
//有时候,我们需要输出矩阵的某一个元素的值,有时候需要用题中的数据与矩阵中的
//某些元素的值再次相乘,得出正确答案
printf("%lld\n",ans);
return 0;
}