12
思路:刚开始看到这个题目想的是纯模拟,但是高达了2^31-1,所以不可以,后来队友告诉我,可以构造出来一个递推的式子
|1 10 1| |fn-1| |fn|
|0 10 1| |xn-1|=|xn|
|0 0 1| |a | |a|
|1 10 1|^n-1 |f1| |fn|
|0 10 1| |x1|=|xn|
|0 0 1| |a | |a|
#include
using namespace std;
typedef long long ll;
/*1 10 1||fn-1| |fn|
0 10 1||xn-1|=|xn|
0 0 1||a | |a|
*/
int a,b,MOD;
struct mat
{
ll a[3][3]; //数组a(一般为存在幂的数组) 3为方阵的长宽
};
mat mat_mul(mat x,mat y)
{
mat res;
memset(res.a,0,sizeof(res.a)); //初始化
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
res.a[i][j]=(res.a[i][j]+x.a[i][k]*y.a[k][j])%MOD; //矩阵乘法
return res;
}
void mat_pow(int n)
{
mat c,res;
c.a[0][0]=1,c.a[0][1]=10,c.a[0][2]=1;
c.a[1][0]=0,c.a[1][1]=10,c.a[1][2]=1;
c.a[2][0]=0,c.a[2][1]=0,c.a[2][2]=1; //初始化赋值需要幂乘的数组
memset(res.a,0,sizeof(res.a));
for(int i=0;i<3;i++) res.a[i][i]=1; //初始化 a的n次方的数组且对角线均为1
while(n)
{
if(n&1) res=mat_mul(res,c);
c=mat_mul(c,c);
n=n>>1;
} //矩阵快速幂的运算过程
int f1=a%MOD,x=a; //数组b的构成
printf("%lld\n",(res.a[0][0]*f1+res.a[0][1]*x+res.a[0][2]*a)%MOD);
}
int main()
{
int n;
while(scanf("%d%d%d",&a,&n,&MOD)==3)
{
mat_pow(n-1);
}
return 0;
}