Description
Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.
Input
The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 109) and m (m < 104). Then follow n lines each containing n nonnegative integers below 32,768, giving A’s elements in row-major order.
Output
Output the elements of S modulo m in the same way as A is given.
Sample Input
2 2 4 0 1 1 1
Sample Output
1 2 2 3
思路:
将之进行两次二分。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n,m,k;
struct node
{
int map[50][50];
node()
{
memset(map,0,sizeof(map));
}
}s,e;
void read()
{
scanf("%d%d%d",&n,&k,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&s.map[i][j]);
s.map[i][j]%=m;
}
for(int i=1;i<=n;i++)e.map[i][i]=1;
}
node add(node a,node b)
{
node c;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
c.map[i][j]=(a.map[i][j]+b.map[i][j])%m;
}
return c;
}
node mut(node a,node b)
{
node c;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int p=1;p<=n;p++)
{
c.map[i][j]=(c.map[i][j]+(a.map[i][p]*b.map[p][j])%m)%m;
}
return c;
}
node pow(node x,int y)
{
node c;
for(int i=1;i<=n;i++)c.map[i][i]=1;
while(y)
{
if(y&1)c=mut(c,x);
y=y>>1;
x=mut(x,x);
}
return c;
}
node ask(node x,int y)
{
if(y==0)return e;
if(y==1)return x;
if(y==2)return add(x,mut(x,x));
if(y%2==1)return add(pow(x,y),ask(x,y-1));
if(y%2==0)
{
node c=pow(x,y/2);
node ans=ask(x,y/2);
node d=mut(c,ans);
return add(d,ans);
}
}
void work()
{
node v=ask(s,k);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
printf("%d ",v.map[i][j]);
}
printf("\n");
}
}
int main()
{
read();
work();
return 0;
}
本文介绍了一种使用矩阵快速幂解决特定数学问题的方法,通过两次二分的方式高效计算矩阵A的幂次和S=A+A^2+A^3+...+A^k(k为正整数),并给出了详细的C++实现代码。
379

被折叠的 条评论
为什么被折叠?



