UVa 11149 Power of Matrix(倍增法、矩阵快速幂)

题目链接: 传送门

Power of Matrix

Time Limit: 3000MS     

Description

给一个n阶方阵,求A1+A2+A3+......Ak。

思路

A1+A2+...+An = (A1+A2+...+An/2)+(A1+A2+...+An/2) * An/2 = (1 + An/2 ) * (A1+A2+...+An/2)那么对于 (A1+A2+...+An/2)也能用同样的方法去求,不断对半下去计算,最后总体复杂度为log(n)^2

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 50;
const int mod = 10;

struct Matrix
{
    int mat[50][50];
    int r,c;
    Matrix(int r1 = 0,int c1 = 0):r(r1),c(c1)
    {
        memset(mat,0,sizeof(mat));
    }
    void E()
    {
        memset(mat,0,sizeof(mat));
        for (int i = 0;i < r;i++)
        {
        	for (int j = 0;j < c;j++)
        	{
        		mat[i][j] = (i == j);
        	}
        }
    }
    Matrix operator+(const Matrix & m)
    {
        Matrix res(r,c);
        for (int i = 0; i < r; i++)
        {
            for (int j = 0; j < c; j++)
            {
                res.mat[i][j] = (mat[i][j] + m.mat[i][j])%mod;
            }
        }
        return res;
    }

    Matrix operator * (const Matrix & m)
    {
        Matrix res(r,m.c);
        for (int i = 0; i < r; i++)
        {
            for (int j = 0; j < m.c; j++)
            {
				for (int k = 0; k < c; k++)
                {
                    res.mat[i][j] = (res.mat[i][j] + mat[i][k] * m.mat[k][j])%mod;
                }
            }
        }
        return res;
    }
    void show()
    {
    	for (int i = 0;i < r;i++)
		{
			bool first = true;
			for (int j = 0;j < c;j++)
			{
				first?printf("%d",mat[i][j]):printf(" %d",mat[i][j]);
				first = false;
			}
			printf("\n");
		} 
    }
};

Matrix pow(Matrix x,int n)
{
	Matrix res(x.r,x.c);
	res.E();
	while (n > 0)
	{
		if (n&1)
		{
			res = res * x;
		}
		x = x * x;
		n >>= 1;
	}
	return res;
}

Matrix sum(Matrix mat,int k)
{
	if (k == 1)
	{
		return mat;
	}
	Matrix E(mat.r,mat.c);
	E.E();
	if (k&1)
	{
		return (E + pow(mat,k/2))*sum(mat,k/2) + pow(mat,k);
	}
	else
	{
		return (E + pow(mat,k/2))*sum(mat,k/2);
	}
}


int main()
{
    int n,k;
    while (~scanf("%d%d",&n,&k) && n && k)
    {
        Matrix Mat(n,n);
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                scanf("%d",&Mat.mat[i][j]);
                Mat.mat[i][j] %= mod;
            }
        }
        if (k == 0)
        {
        	Mat.show();
        	continue;
        }
        Mat = sum(Mat,k);
        Mat.show();
        printf("\n");
    }
    return 0;
}
posted @   zxzhang  阅读(191)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示

目录导航