Additions HNUST 1713(矩阵快速幂模板 )
2017-12-08 16:24
267 查看
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;
}
相关文章推荐
- (模板题)sdut 3359 高数Umaru系列(10)——简单题(矩阵快速幂)
- HDU1575:Tr A(矩阵快速幂模板题)
- hdu1575 Tr A(矩阵快速幂模板题)
- HDU2604 Queuing(矩阵快速幂模板)
- 矩阵乘法+快速幂——【模板】矩阵快速幂
- 矩阵快速幂模板
- 那啥,,矩阵乘法,矩阵快速幂模板
- 矩阵快速幂模板
- 洛谷P3390 【模板】矩阵快速幂
- 矩阵快速幂模板
- 洛谷P3390 【模板】矩阵快速幂
- 斐波那契数列的第N项(矩阵快速幂模板)
- luogu P3390 【模板】矩阵快速幂
- 矩阵快速幂 模板
- 【模板】矩阵快速幂
- Fibonacci----poj3070(矩阵快速幂, 模板)
- HDU1575--Tr A(矩阵快速幂模板)
- POJ 3070 Fibonacci 【矩阵快速幂取模 (模板)】
- 矩阵快速幂模板
- 矩阵快速幂模板 参考bjfu1440