关闭

POJ3233 矩阵的N次幂求和 二分

219人阅读 评论(0) 收藏 举报

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;
}


0
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:116488次
    • 积分:2289
    • 等级:
    • 排名:第16276名
    • 原创:108篇
    • 转载:26篇
    • 译文:0篇
    • 评论:17条
    最新评论