UVA 11149 Power of Matrix(矩阵+二分)
2016-07-28 10:23
393 查看
此文章可以使用目录功能哟↑(点击上方[+])
Accept: 0 Submit: 0
Time Limit: 3000 MS
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.
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.
3 2
0 2 0
0 0 2
0 0 0
0 0
0 2 4
0 0 2
0 0 0
解题思路:
【题意】
给你一个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
/*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
;
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 Problem 11149 Power of Matrix
Accept: 0 Submit: 0Time 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
3 20 2 0
0 0 2
0 0 0
0 0
Sample Output
0 2 40 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
;
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;
}
菜鸟成长记
相关文章推荐
- Android开发笔记(-)初识Android中的px,sp,dp
- GitHub相关
- Pro JPA2读书笔记系列(十二)-第十一章(高级主题)
- QProcess::readAll() 函数
- Hadoop:HDFS的数据复制
- udev使用方法(附实例)
- 易买网项目总结
- seajs
- 多媒体应用-swift
- C++ STL--stack/queue 的使用方法
- HDU 4588 Count The Carries(数学)
- 获取字符中Url地址
- mysql 字符集(CHARACTER SET)和校对集(COLLATE)
- 网络请求xml PULL解析
- 友盟统计使用记录
- SVN服务器搭建 <1>
- Pro JPA2读书笔记系列(十一)-第十章(高级对象-关系映射)
- Hadoop:HDFS文件存取机制
- fixed 定位 苹果手机输入框触发时内容全部隐藏
- NIO中Selector分析