sum of squares of matrices in ac number theory

Matrix Power Series

Time Limit: 1000  ms | Memory Limit: 65535  KB
Difficulty: 4
describe
Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.
enter
The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 10^9) and m (m < 10^4). 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


Problem solving ideas:

the first method:

The question means a given matrix A (represented by ori in the following code). And k, mod , find the sum of A+A^2+A^3+...A^k and take the remainder of mod.

At the beginning, use the loop k times, recursive approach, and timeout.

。。

Looking at the problem solving report, the sum of two points is used when summing.

The desired sum is denoted by s(k).

When k is even:

Ratio k = 6, Najo A + A ^ 2 + A ^ 3 + A ^ 4 + A ^ 5 + A ^ 6 = A + A ^ 2 + A ^ 3 + A ^ 3 * (A + A ^ 2 + A) ^ 3)   

s(k)=s(k/2)+A^(n/2) * s(k/2) ie s(k)=(E+A^(n/2))*s(n/2) (E is the identity matrix)

When k is odd:

s(k)=s(k-1)+A^k , then k-1 is even. According to the above two points

PS: The code should be written carefully, otherwise a small error will be checked for a long time... ret.arr[i][j]+=a.arr[i][k]*b.arr when calculating the multiplication of two matrices [k][j]; actually written as ret.arr[i][j]+=a.arr[i][k]*a.arr[k][j]; TT

Code:


#include<iostream>
#include<string.h>
using namespace std;;
int n;
int m;
int k;
#define MAXN 40
typedef struct node//The purpose of setting the structure is purely to pass the value for convenience
{
	int data[MAXN][MAXN];
	node()//The constructor of the structure
	{
		memset(data,0,sizeof(data));
	}
} Matri;//Define the matrix structure
Matri ma;//Define the required matrix
Matri multi_mod(Matri a,Matri b)//定义矩阵的的相乘函数并且返回给另一个矩阵,一定要注意矩阵的乘法先后顺序是不能够颠倒的
{
	Matri c;//保存最终结果并要返回的矩阵
	for(int i=0; i<n; i++)
		for(int j=0; j<n; j++)
			for(int k=0; k<n; k++)
			{
				c.data[i][j]+=a.data[i][k]*b.data[k][j];//按照矩阵乘法规则来
				c.data[i][j]%=m;//按照题目要求取余
			}
			return c;//返回结果矩阵
}
Matri add(Matri a,Matri b)//定义矩阵的加法
{
	for(int i=0; i<n; i++)
		for(int j=0; j<n; j++)
		{
			a.data[i][j]+=b.data[i][j];//对应项相加
			a.data[i][j]%=m;
		}
		return a;//返回结果矩阵
}
Matri fast_power(Matri a,int fn)//矩阵的快速幂
{
	Matri result;//定义单位矩阵
	for(int i=0;i<n;i++)
		result.data[i][i]=1;//对角线权为1
	while(fn>0)
	{
		if(fn%2==1)
			result=multi_mod(result,a);//调用乘法注意相乘顺序
		a=multi_mod(a,a);
		fn=fn/2;
	}
	return result;//返回结果矩阵
}
Matri op(int opn,Matri r)//按照题目要求进行操作
{ 
	if(opn==1)//如果是一次方,返回原来的数组自己
		return r;
	if(opn%2==0)//如果是偶数那么就返回s(n/2)+s(n/2)*a^(n/2)
	{
		Matri aa=op(opn/2,r);
		Matri bb=fast_power(r,opn/2);
		r=add(aa,multi_mod(bb,aa));
	}
	else r= add(op(opn-1,r),fast_power(ma,opn));//如果是奇数那么就返回s(n-1)*a^(n)
	return r;
}
int main()
{
	cin>>n>>k>>m;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			cin>>ma.data[i][j];
		}
	}

	Matri result=op(k,ma);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
			cout<<result.data[i][j]<<" ";
		cout<<endl;
	}
}

还有一种方法是构造矩阵的我就不在写了,很巧妙,只需快速幂,矩阵乘法与矩阵的合成与分离就OK,我贴个地址么么哒!

以下转自该地址博主

https://www.cnblogs.com/hadilo/p/5903514.html






Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326483774&siteId=291194637