Additions HNUST 1713(矩阵快速幂模板 )
2017-12-08 16:24
295 查看
Ada is 5 years old, and she is learning additions. Her father writes some exercises for her.
1+11=?
2+22=?
3+33=?
“It is easy”, she writes the answer correctly. “Try to answer the following questions”,
1+11+111=?
2+22+222+2222=?
Ada scratches her head. “It’s too difficult”.
So, help Ada to compute the value of equation a+aa+aaa+... which have n items. Since the answer may be quite large, you have to module it by an integer m.
输入
Input contains at most 1000 test cases. Each test case contains only one line.
Each line will contain three integers a, n and m. (1<=a<=9, 1<=n<231-1, 1<=m<=100007). Process to end of file.
输出
For each test cases, output the value of (a+aa+aaa+... .)%m。
样例输入
1 1 13
1 2 13
1 3 13
2 2 13
2 3 13
样例输出
1
12
6
11
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<bits/stdc++.h>
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;
}
1+11=?
2+22=?
3+33=?
“It is easy”, she writes the answer correctly. “Try to answer the following questions”,
1+11+111=?
2+22+222+2222=?
Ada scratches her head. “It’s too difficult”.
So, help Ada to compute the value of equation a+aa+aaa+... which have n items. Since the answer may be quite large, you have to module it by an integer m.
输入
Input contains at most 1000 test cases. Each test case contains only one line.
Each line will contain three integers a, n and m. (1<=a<=9, 1<=n<231-1, 1<=m<=100007). Process to end of file.
输出
For each test cases, output the value of (a+aa+aaa+... .)%m。
样例输入
1 1 13
1 2 13
1 3 13
2 2 13
2 3 13
样例输出
1
12
6
11
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<bits/stdc++.h>
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;
}
相关文章推荐
- 模板【洛谷P3390】 【模板】矩阵快速幂
- hdoj 1588 矩阵快速幂 二分等比数列求和模板
- 矩阵快速幂模板
- 矩阵快速幂模板
- 矩阵快速幂 模板
- Tr A (矩阵快速幂(模板))
- poj 3070 Fibonacci(矩阵快速幂模板,斐波那契)
- HDU 1757 A Simple Math Problem(矩阵快速幂模板)
- 矩阵快速幂模板
- [模板] - 矩阵快速幂
- 洛谷P3390 【模板】矩阵快速幂
- 洛谷P3390 【模板】矩阵快速幂
- 深夜敲模板_1——快速幂 && 矩阵的快速幂
- POJ3070 矩阵快速幂模板题
- Covering HDU - 6185 矩阵快速幂 or杜教模板
- poj 3070 矩阵快速幂模板
- 模板——矩阵快速幂
- 矩阵快速幂模板
- 矩阵快速幂 模板
- hdoj 1575 Tr A(矩阵快速幂,模板题)