[Template] Matrix Fast Power

topic background

Matrix fast exponentiation

Topic description

Given an n*n matrix A, find A^k

Input and output format

Input format:

The first row, n,k

Rows 2 to n+1, each row has n numbers, and the jth number in row i+1 represents the element in row i and column j of the matrix

Output format:

output A^k

A total of n rows, each row has n numbers, the i-th row and the j-th number represent the elements of the i-th row and the j-th column of the matrix, each element modulo 10^9+7

illustrate

n<=100, k<=10^12, |Matrix Elements|<=1000 Algorithm: Matrix Fast Power

Ideas:

A template matrix fast exponentiation

First understand what is matrix multiplication

For example, the f[][] matrix is ​​multiplied by j[][], and the answer matrix is ​​ans[2][2]

则ans[1][1]=f[1][1]*j[1][1]+f[1][2]*j[2][1]+.....+f[1 ][k]*j[k][1]

ans[1][2]=f[1][1]*j[1][2]+f[1][2]*j[2][2]+.....+f[1] [k]*j[k][2]

That is to say, each element of ans[a][b]=Σf[a][1~k] is multiplied by each element of j[1~k][b]

As shown in the figure:

Half of the mission is over, but it's still short of fast power

I believe you are not naive enough to scan o(k) once in the case of k=10^12

How to do? ?
Quick power comes to the rescue

 For details about fast power, please refer to my other blog

time down to o(logn);

pass

Code:

#include<iostream>
#include<cstdio>
#define rii register int i
#define row register int j
#define rik register int k
using namespace std;
long long x[105][105],zcq[105][105],ls[105][105],n,k,mod=1e9+7;
void cf2()
{
	long long ans=0;
    for(rii=1;i<=n;i++)
    {
    	for(rij=1;j<=n;j++)
     	{
			ls[i][j]=zcq[i][j];
		 }
	}
	for(rii=1;i<=n;i++)
	{
		for(rij=1;j<=n;j++)
		{
			for(rik=1;k<=n;k++)
    		{
				ans + = (x [i] [k] * ls [k] [j])% mod;
				ans=ans%mod;
			}
			zcq[i][j]=ans%mod;
			years=0;
		}
	}
}
void cf1()
{
	long long ans=0;
    for(rii=1;i<=n;i++)
    {
    	for(rij=1;j<=n;j++)
    	{
    		ls[i][j]=x[i][j];
		}
	}
    for(rii=1;i<=n;i++)
    {
    	for(rij=1;j<=n;j++)
    	{
    		for(rik=1;k<=n;k++)
    		{
    			ans+=(ls[i][k]*ls[k][j])%mod;
				ans=ans%mod;
			}
			x [i] [j] = ans% mod;
			years=0;
		}
	}
}
void ksm(long long k)
{
	if(k==0)
	{
		return;
	}
	if(k%2==0)
	{
		cf1();
		ksm (k / 2);
		return;
	}
	else
	{
		cf2();
		ksm (k-1);
		return;
	}
}
intmain()
{
    scanf("%lld%lld",&n,&k);
    for(rii=1;i<=n;i++)
    {
    	for(rij=1;j<=n;j++)
    	{
    		scanf("%d",&x[i][j]);
			zcq[i][j]=x[i][j];
		}
	}
    ksm (k-1);
    for(rii=1;i<=n;i++)
    {
    	for(rij=1;j<=n;j++)
    	{
    		printf("%ld ",zcq[i][j]);
		}
    	printf("\n");
    }
}

 

Guess you like

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