题目链接: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 的快速幂里的每个乘法都是 n级别的了,n 的上限为1000,这样子超时也不奇怪了,怎么办呢,原来是要转化一下:(A*B)n*n= A*(B*A)n*n-1*A,这样子的话,B*A 是 k*k 的矩阵,乘法是 k级别的,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的更多相关文章

  1. hdu 4965 Fast Matrix Calculation(矩阵高速幂)

    题目链接.hdu 4965 Fast Matrix Calculation 题目大意:给定两个矩阵A,B,分别为N*K和K*N. 矩阵C = A*B 矩阵M=CN∗N 将矩阵M中的全部元素取模6,得到 ...

  2. HDU 4965 Fast Matrix Calculation(矩阵高速幂)

    HDU 4965 Fast Matrix Calculation 题目链接 矩阵相乘为AxBxAxB...乘nn次.能够变成Ax(BxAxBxA...)xB,中间乘n n - 1次,这样中间的矩阵一个 ...

  3. 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 ...

  4. HDU 4965 Fast Matrix Calculation 矩阵快速幂

    题意: 给出一个\(n \times k\)的矩阵\(A\)和一个\(k \times n\)的矩阵\(B\),其中\(4 \leq N \leq 1000, \, 2 \leq K \leq 6\) ...

  5. HDU 4965 Fast Matrix Calculation 矩阵乘法 乘法结合律

    一种奇葩的写法,纪念一下当时的RE. #include <iostream> #include <cstdio> #include <cstring> #inclu ...

  6. hdu4965 Fast Matrix Calculation (矩阵快速幂 结合律

    http://acm.hdu.edu.cn/showproblem.php?pid=4965 2014 Multi-University Training Contest 9 1006 Fast Ma ...

  7. HDU4965 Fast Matrix Calculation —— 矩阵乘法、快速幂

    题目链接:https://vjudge.net/problem/HDU-4965 Fast Matrix Calculation Time Limit: 2000/1000 MS (Java/Othe ...

  8. 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 ...

  9. 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 ...

随机推荐

  1. 在Windows Live Writer中插入C# code

    平时都是用Windows Live Writer写博客,发布博客.遇到需要插入代码都是先在notepad中写好,或者是拷贝到notepad,再从notepad中拷到Windows Live Write ...

  2. 20150916_001 vba 基础

    一.什么是“宏”.“宏”有什么用 关于“宏”的详细定义,可以参考百度百科的解释(点击查看).我给它一个简单的或许不太严谨的定义: 宏的通俗定义:宏是被某些软件所能识别.理解并执行的特定代码/脚本. 宏 ...

  3. python-haproxy作业讲解视频总结

    刚看完瞎驴的haproxy配置文件的作业讲解视频: 总结: 1.用户输入的字符串数据类型转换其他数据类型 1.1 eval('用户输入的数据') 1.2 json.loads('用户输入的数据') 2 ...

  4. Python学习笔记-Day2-Python基础之字典操作

    字典的常用操作包括但不限于以下操作: 字典的字典的索引,新增,删除,循环,长度等等 这里将对列表的内置操作方法进行总结归纳,重点是以示例的方式进行展示. 使用type获取创建对象的类 type(dic ...

  5. Redis的WEB界面管理工具phpRedisAdmin

    下载地址:http://down.admin5.com/php/75024.html 官方网址:https://github.com/ErikDubbelboer/phpRedisAdmin

  6. spring容器启动过程

    1.AbstractApplicationContext的prepareRefresh()方法调用. 2.XmlBeanDefinitionReader的loadBeanDifinitions(Bea ...

  7. zookeeper系列之二—zookeeper历史

    Zookeeper是什么? Zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby的一个开源版本.它是为分布式应用提供一致性服务的软件,提供的功能包括:配置服 ...

  8. js九宫格的碰撞检测

    说来惭愧,我一直以为四四方方的拖拽碰撞检测是一个比较容易的事情,后来试过一次,真是让我耗费了无数的脑细胞,原理其实不难,但是具体做起来可就让我很恶心,这可能跟我驾驭的代码数量有关系,我一般也就写半屏幕 ...

  9. [转]C# List<T>的详细用法

    所属命名空间:System.Collections.Generic publicclassList<T> : IList<T>,ICollection<T>, IE ...

  10. Using Post-Form Trigger In Oracle Forms

    Post-Form trigger in Oracle Forms fires during the Leave the Form process, when a form is exited.   ...