POJ3233 矩阵的N次幂求和 二分

k 为偶数:A^k = A ^(k/2) * A ^(k/2);

k 为奇数: A^k = A ^ (k/2) * A^(k/2) * A

  

n  = 2k 为偶数

A^1 + A^2 + A^3 +....... A^(2k) = (A + A^2 + A^3 + .....A ^ k) + A^k * (A + A^2 + A^3 + .....A ^ k);


n = 2k + 1为奇数

A^1 + A^2 + A^3 +....... A^(2k + 1) = (A + A^2 + A^3 + .....A ^ k) +A ^(k + 1) + A^(k + 1) * (A + A^2 + A^3 + .....A ^ k);


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
struct MATRIX
{
	int m[35][35];
};
int m;
MATRIX MOD(MATRIX num1,int n)
{
	int i,j;
	MATRIX res;
	for(i = 0; i < n; i++)
	{
		for(j = 0; j < n; j++)
		{
			res.m[i][j] = res.m[i][j]  %  m;
			
		}
	}
	return res;
}
MATRIX  mul(MATRIX num1, MATRIX num2,int n)
{
	int x;
	int i,j;
	MATRIX res;
	memset(&res,0,sizeof(res));
	for(i = 0; i <n; i++)
	{
		for(j = 0; j < n; j++)
		{
			for(x = 0; x < n; x++)
			{
				res.m[i][j] += (num1.m[i][x] * num2.m[x][j]) % m;
				res.m[i][j] %= m;
			
			}
		}
	}

	return res;
}
MATRIX sum(MATRIX num1,MATRIX  num2, int n)
{
	int i,j;
	MATRIX result;
	for(i = 0; i < n; i++)
	{
		for(j = 0; j < n; j++)
		{
			result.m[i][j] = (num1.m[i][j] + num2.m[i][j]) % m;
			
		}
	}
	return result;//Why not res
}
MATRIX POW(MATRIX mat,int n,int t)
{
	if(t == 1)
	{
		return  mat;

	}
	MATRIX res;
	if(t % 2 == 0)
	{
		res = POW(mat,n, t/2);
		MATRIX current;
		memcpy(¤t, &res, sizeof(res));

		res = mul(current,res,n);
	}
	else
	{
		res = POW(mat,n,t/2);
		res = mul(res,res,n);
		res = mul(res,mat,n);	
	}
	return res;

}
MATRIX total(MATRIX mat,int k,int n)
{
	MATRIX current;
	MATRIX res;
	if(k == 1)
	{
		return mat;
	}
	if(k % 2 == 0)
	{
		current = total(mat,k/2,n);
		res = sum(current,mul(current , POW(mat,n,k/2),n),n);
		return res;

		
	}
	else
	{
		current = total(mat,k/2,n);
		  MATRIX flag = POW(mat,n,k/2 + 1);
		  MATRIX flag1;
		  flag1 = sum(current, flag,n);
		  res = sum(flag1,mul(flag,current,n),n);
		  return res;
	}
	

}
int main()
{
	int n,k;
	while(scanf("%d %d %d",&n,&k,&m) != EOF)
	{
		MATRIX num;
		MATRIX res;
		memset(&num,0,sizeof(num));
		memset(&res,0,sizeof(res));

		int i,j;
		for(i = 0; i < n; i++)
		{
			for(j = 0; j < n; j++)
			{
				scanf("%d",&num.m[i][j]);
			}
		}
		MOD(num, n);
		res = total(num, k,n);
		MOD(num, n);
			for(i = 0; i < n; i++)
		{
			for(j = 0; j < n; j++)
			{
				printf("%d%c",res.m[i][j],j != n-1? ' ':'\n');
			}
		}
	}
	return 0;
}


以下是Java解决POJ3233矩阵序列问题的代码和解释: ```java import java.util.Scanner; public class Main { static int n, k, m; static int[][] A, E; public static void main(String[] args) { Scanner sc = new Scanner(System.in); n = sc.nextInt(); k = sc.nextInt(); m = sc.nextInt(); A = new int[n][n]; E = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { A[i][j] = sc.nextInt() % m; E[i][j] = (i == j) ? 1 : 0; } } int[][] res = matrixPow(A, k); int[][] ans = matrixAdd(res, E); printMatrix(ans); } // 矩阵乘法 public static int[][] matrixMul(int[][] a, int[][] b) { int[][] c = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < n; k++) { c[i][j] = (c[i][j] + a[i][k] * b[k][j]) % m; } } } return c; } // 矩阵快速 public static int[][] matrixPow(int[][] a, int b) { int[][] res = E; while (b > 0) { if ((b & 1) == 1) { res = matrixMul(res, a); } a = matrixMul(a, a); b >>= 1; } return res; } // 矩阵加法 public static int[][] matrixAdd(int[][] a, int[][] b) { int[][] c = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { c[i][j] = (a[i][j] + b[i][j]) % m; } } return c; } // 输出矩阵 public static void printMatrix(int[][] a) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { System.out.print(a[i][j] + " "); } System.out.println(); } } } ``` 解释: 1. 首先读入输入的n、k、m和矩阵A,同时初始化单位矩阵E。 2. 然后调用matrixPow函数求出A的k矩阵res。 3. 最后将res和E相加得到结果ans,并输出。 4. matrixMul函数实现矩阵乘法,matrixPow函数实现矩阵快速matrixAdd函数实现矩阵加法,printMatrix函数实现输出矩阵
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值