hdu 4965 Fast Matrix Calculation
题目链接:hdu 4965,题目大意:给你一个 n*k 的矩阵 A 和一个 k*n 的矩阵 B,定义矩阵 C= A*B,然后矩阵 M= C^(n*n),矩阵中一切元素皆 mod 6,最后求出 M 中所有元素的和。题意很明确了,便赶紧敲了个矩阵快速幂的模板(因为编程的基本功不够还是调试了很久),然后提交后TLE了,改了下细节,加了各种特技,比如输入优化什么的,还是TLE,没办法,只好搜题解,看了别人的题解后才知道原来 A*B 已经是 n*n 的矩阵了,所以(A*B)n*n 的快速幂里的每个乘法都是 n3 级别的了,n 的上限为1000,这样子超时也不奇怪了,怎么办呢,原来是要转化一下:(A*B)n*n= A*(B*A)n*n-1*A,这样子的话,B*A 是 k*k 的矩阵,乘法是 k3 级别的,k<=6,就不会超时了,这个转化果然好厉害!
如果结构体内直接开个数组的话会超内存,要用指向一维数组的指针来 new 才行,不过还是很容易出错:
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
#define For(i,s,t) for(int i=s; i<=t; ++i)
const int mod= ;
const int maxn= ; struct matrix{
int n,m, (*a)[maxn]= NULL;
matrix(int n=, int m=):n(n),m(m){
a= new int[n+][maxn];
For(i,,n) For(j,,m)
a[i][j]= ;
}
void identity(){
For(i,,n) a[i][i]= ;
}
matrix operator *(const matrix &m2) const {
matrix mul(n,m2.m);
For(i,,n) For(j,,m2.m) For(k,,m)
mul.a[i][j]= (mul.a[i][j]+a[i][k]*m2.a[k][j]%mod)%mod;
return mul;
}
int sum(){
int ans= ;
For(i,,n) For(j,,m)
ans+= a[i][j];
return ans;
}
void clear() { delete[] a; }
}; matrix quick_mod(matrix m2, int p){
matrix ans(m2.n,m2.m);
ans.identity();
while(p){
if(p&) ans= ans*m2;
m2= m2*m2;
p>>=;
}
return ans;
} void read(int &x){
x= ;
char ch= getchar();
while(!isdigit(ch)) ch= getchar();
while(isdigit(ch)){
x= x*+(ch-''+);
ch= getchar();
}
} int main(){
int n,k;
read(n); read(k);
while(){
if(!n || !k) break;
matrix A(n,k), B(k,n), tmp(k,k), C(n,n);
For(i,,n) For(j,,k) read(A.a[i][j]);
For(i,,k) For(j,,n) read(B.a[i][j]);
tmp= B*A;
tmp= quick_mod(tmp,n*n-);
C= A*tmp*B;
printf("%d\n",C.sum());
read(n); read(k);
A.clear();
B.clear();
tmp.clear();
C.clear();
}
return ;
}
用指向一维数组的指针貌似挺耗费内存的,于是改用了二级指针来试下,果然内存和效率都明显有了很大的提高(但好像还是比不上 vector 耶~):
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
#define For(i,s,t) for(int i=s; i<=t; ++i)
const int mod= ;
const int maxn= ; struct matrix{
int n,m, **a= NULL;
matrix(int n=, int m=):n(n),m(m){
a= new int *[n+];
For(i,,n) a[i]= new int[m+];
For(i,,n) For(j,,m)
a[i][j]= ;
}
void identity(){
For(i,,n) a[i][i]= ;
}
matrix operator *(const matrix &m2) const {
matrix mul(n,m2.m);
For(i,,n) For(j,,m2.m) For(k,,m)
mul.a[i][j]= (mul.a[i][j]+a[i][k]*m2.a[k][j]%mod)%mod;
return mul;
}
int sum(){
int ans= ;
For(i,,n) For(j,,m)
ans+= a[i][j];
return ans;
}
void clear(){
For(i,,n) delete a[i];
delete a;
a = NULL;
}
}; matrix quick_mod(matrix m2, int p){
matrix ans(m2.n,m2.m);
ans.identity();
while(p){
if(p&) ans= ans*m2;
m2= m2*m2;
p>>=;
}
return ans;
} void read(int &x){
x= ;
char ch= getchar();
while(!isdigit(ch)) ch= getchar();
while(isdigit(ch)){
x= x*+(ch-''+);
ch= getchar();
}
} int main(){
int n,k;
read(n); read(k);
while(){
if(!n || !k) break;
matrix A(n,k), B(k,n), tmp(k,k), C(n,n);
For(i,,n) For(j,,k) read(A.a[i][j]);
For(i,,k) For(j,,n) read(B.a[i][j]);
tmp= B*A;
tmp= quick_mod(tmp,n*n-);
C= A*tmp*B;
printf("%d\n",C.sum());
read(n); read(k);
A.clear();
B.clear();
tmp.clear();
C.clear();
}
return ;
}
后来无意中看到别人的代码用 vector 来代替动态数组就行,不用自己手动 new 和 delete 了,确实方便了好多:
#include<cstdio>
#include<cstring>
#include<cctype>
#include<vector>
#include<algorithm>
using namespace std;
#define For(i,s,t) for(int i=s; i<=t; ++i)
const int mod= ;
const int maxn= ; struct matrix{
int n,m;
vector<vector<int> > a;
matrix(int n=, int m=):n(n),m(m){
a.resize(n+);
For(i,,n) a[i].resize(m+,);
}
void identity(){
For(i,,n) a[i][i]= ;
}
matrix operator *(const matrix &m2) const {
matrix mul(n,m2.m);
For(i,,n) For(j,,m2.m) For(k,,m)
mul.a[i][j]= (mul.a[i][j]+a[i][k]*m2.a[k][j]%mod)%mod;
return mul;
}
int sum(){
int ans= ;
For(i,,n) For(j,,m)
ans+= a[i][j];
return ans;
}
~matrix() {
For(i,,n) a[i].clear();
a.clear();
}
}; matrix quick_mod(matrix m2, int p){
matrix ans(m2.n,m2.m);
ans.identity();
while(p){
if(p&) ans= ans*m2;
m2= m2*m2;
p>>=;
}
return ans;
} void read(int &x){
x= ;
char ch= getchar();
while(!isdigit(ch)) ch= getchar();
while(isdigit(ch)){
x= x*+(ch-''+);
ch= getchar();
}
} int main(){
int n,k;
read(n); read(k);
while(){
if(!n || !k) break;
matrix A(n,k), B(k,n), tmp(k,k), C(n,n);
For(i,,n) For(j,,k) read(A.a[i][j]);
For(i,,k) For(j,,n) read(B.a[i][j]);
tmp= B*A;
tmp= quick_mod(tmp,n*n-);
C= A*tmp*B;
printf("%d\n",C.sum());
read(n); read(k);
}
return ;
}
看来自己曾经引以为傲的矩阵快速幂还差得很远啊~~总之得加把劲了!
hdu 4965 Fast Matrix Calculation的更多相关文章
- hdu 4965 Fast Matrix Calculation(矩阵高速幂)
题目链接.hdu 4965 Fast Matrix Calculation 题目大意:给定两个矩阵A,B,分别为N*K和K*N. 矩阵C = A*B 矩阵M=CN∗N 将矩阵M中的全部元素取模6,得到 ...
- HDU 4965 Fast Matrix Calculation(矩阵高速幂)
HDU 4965 Fast Matrix Calculation 题目链接 矩阵相乘为AxBxAxB...乘nn次.能够变成Ax(BxAxBxA...)xB,中间乘n n - 1次,这样中间的矩阵一个 ...
- HDU - 4965 Fast Matrix Calculation 【矩阵快速幂】
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4965 题意 给出两个矩阵 一个A: n * k 一个B: k * n C = A * B M = (A ...
- HDU 4965 Fast Matrix Calculation 矩阵快速幂
题意: 给出一个\(n \times k\)的矩阵\(A\)和一个\(k \times n\)的矩阵\(B\),其中\(4 \leq N \leq 1000, \, 2 \leq K \leq 6\) ...
- HDU 4965 Fast Matrix Calculation 矩阵乘法 乘法结合律
一种奇葩的写法,纪念一下当时的RE. #include <iostream> #include <cstdio> #include <cstring> #inclu ...
- hdu4965 Fast Matrix Calculation (矩阵快速幂 结合律
http://acm.hdu.edu.cn/showproblem.php?pid=4965 2014 Multi-University Training Contest 9 1006 Fast Ma ...
- HDU4965 Fast Matrix Calculation —— 矩阵乘法、快速幂
题目链接:https://vjudge.net/problem/HDU-4965 Fast Matrix Calculation Time Limit: 2000/1000 MS (Java/Othe ...
- Fast Matrix Calculation HDU - 4965
One day, Alice and Bob felt bored again, Bob knows Alice is a girl who loves math and is just learni ...
- hdu4965 Fast Matrix Calculation 矩阵快速幂
One day, Alice and Bob felt bored again, Bob knows Alice is a girl who loves math and is just learni ...
随机推荐
- Android 自定义ScrollView ListView 体验各种纵向滑动的需求
分类: [android 进阶之路]2014-08-31 12:59 6190人阅读 评论(10) 收藏 举报 Android自定义ScrollView纵向拖动 转载请标明出处:http: ...
- js去除日期字符串时分秒
var date = "2015-11-11 00:00:00"; var newDate=/\d{4}-\d{1,2}-\d{1,2}/g.exec(date) newDate= ...
- Borg Maze 分类: POJ 2015-07-27 15:28 5人阅读 评论(0) 收藏
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9971 Accepted: 3347 Description The B ...
- C#递归1~100的累加
public static int Accum(int m, int n) { //对于接受的参数,要考虑m >n,m=n,m<n三种情况. if (m < n) { return ...
- LTE 切换过程中的数据切换
http://blog.sina.com.cn/s/blog_673b30dd0100j4p4.html LTE中的切换,根据无线承载(Radio Bearer)的QoS要求的不同,可以分为无缝切换( ...
- 修改Windows下的键盘映射
在知乎上看见有人说Ctrl键放在A的旁边会更方便,于是我就琢磨着把Cap Lock键改成Ctrl 我肯定不愿意用第三方工具修改的,于是找到了这篇文章,很容易的就修改成功,现在用起来果然舒服多了. 附上 ...
- Git学习笔记03--git reset
摘自<Git权威指南> Git reset 是Git最常用的命令之一,也是最危险最容易误用的命令. 用法一:git reset [-q] [<commit>] [--] < ...
- Storm系列之二——Guaranteeing Message Processing
Storm保证每跳离开spout的消息都会被完全处理.本文介绍Storm是怎么保证每条消息都被完全处理并且作为用户该怎么做才能从Storm的可靠性保证受益. 1.什么叫消息被完全处理? 一个tuple ...
- 【MySQL】过滤后的结果集较大,用LIMIT查询分页记录,查询效率不理想
> 参考的优秀文章 优化LIMIT分页--<高性能MySQL>(电子工业出版社) > 场景描述 遇到一个场景:查询排序后的结果集较大,我们采用分页显示,每页显示20条记录,但是 ...
- Android 4.4之后删除短信进行处理
android 4.4删除短信 android 4.4之后非默认的短信应用已经没有办法删除短信了.像以前那样用如下方法是不会没法删除短信的(即使在xml中配置了短信的读写权限),同时也不会有报错或其他 ...