此文章可以使用目录功能哟↑(点击上方[+])
UVA Problem 11149 Power of Matrix
Accept: 0 Submit: 0
Time Limit: 3000 MS
Problem Description
Input
Input consists of no more than 20 test cases. The first line for each case contains two positive integers n (≤ 40) and k (≤ 1000000). This is followed by n lines, each containing n non-negative integers, giving the matrix A.
Input is terminated by a case where n = 0. This case need NOT be processed.
Output
For each case, your program should compute the matrix . Since the values may be very large, you only need to print their last digit. Print a blank line after each case.
Sample Input
0 2 0
0 0 2
0 0 0
0 0
Sample Output
0 0 2
0 0 0
Problem Idea
解题思路:
【题意】
给你一个n*n大小的矩阵A,和系数k,求的结果矩阵
由于数据比较大,输出结果矩阵时,每个元素只需输出最后一位数
【类型】
矩阵构造+二分
【分析】
求矩阵,显然是要用到矩阵乘法快速幂的
但是,如果单纯用快速幂求A~,那和直接一项项计算并没有什么区别,复杂度是O(n*n*n*k),显然不够
所以可以采取二分,对于
①当k为奇数时
②当k为偶数时
然后第一个括号里可以进一步化简,直至k=1为止
这里可以递归实现
一开始TLE了好几发,还以为递归实现还不够优化,后来才发现,题目指出,n=0时,输入结束,然而我却判断要0 0才退出
好吧,超时在这里,醉了
【时间复杂度&&优化】
O(n*n*nlogk)
题目链接→UVA 11149 Power of Matrix
Source Code
/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define eps 1e-8
#define LL long long
#define bitnum(a) __builtin_popcount(a)
using namespace std;
const int N = 45;
const int M = 100005;
const int inf = 1000000007;
const int mod = 10;
typedef struct node
{
int a[N][N];
void Init()
{
memset(a,0,sizeof(a));
for(int i=0;i<N;i++)
a[i][i]=1;
}
}matrix;
int n;
matrix mul(matrix a,matrix b)//矩阵乘法
{
matrix ans;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
ans.a[i][j]=0;
for(int k=0;k<n;k++)
ans.a[i][j]+=(a.a[i][k]*b.a[k][j])%mod;
ans.a[i][j]%=mod;
}
return ans;
}
matrix add(matrix a,matrix b)//矩阵加法
{
matrix ans;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
ans.a[i][j]=(a.a[i][j]+b.a[i][j])%mod;
return ans;
}
matrix pow(matrix a,int n)//求a^n
{
matrix ans;
ans.Init();
while(n)
{
if(n%2)
ans=mul(ans,a);
n/=2;
a=mul(a,a);
}
return ans;
}
matrix ans,s;
matrix dfs(int k)
{
if(k==1)
return ans;
if(k%2)
return add(mul(dfs(k/2),add(s,pow(ans,k/2))),pow(ans,k));
else
return mul(dfs(k/2),add(s,pow(ans,k/2)));
}
int main()
{
int k,i,j;
s.Init();
while(scanf("%d%d",&n,&k)&&n)
{
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&ans.a[i][j]),ans.a[i][j]%=10;
ans=dfs(k);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
printf("%d%c",ans.a[i][j],j!=n-1?' ':'\n');
puts("");
}
return 0;
}
菜鸟成长记
解决UVA 11149问题,通过矩阵快速幂算法结合二分查找,高效计算大指数下矩阵的幂,并只输出结果的最后一位数字。
2588

被折叠的 条评论
为什么被折叠?



