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 ...
随机推荐
- 在Windows Live Writer中插入C# code
平时都是用Windows Live Writer写博客,发布博客.遇到需要插入代码都是先在notepad中写好,或者是拷贝到notepad,再从notepad中拷到Windows Live Write ...
- 20150916_001 vba 基础
一.什么是“宏”.“宏”有什么用 关于“宏”的详细定义,可以参考百度百科的解释(点击查看).我给它一个简单的或许不太严谨的定义: 宏的通俗定义:宏是被某些软件所能识别.理解并执行的特定代码/脚本. 宏 ...
- python-haproxy作业讲解视频总结
刚看完瞎驴的haproxy配置文件的作业讲解视频: 总结: 1.用户输入的字符串数据类型转换其他数据类型 1.1 eval('用户输入的数据') 1.2 json.loads('用户输入的数据') 2 ...
- Python学习笔记-Day2-Python基础之字典操作
字典的常用操作包括但不限于以下操作: 字典的字典的索引,新增,删除,循环,长度等等 这里将对列表的内置操作方法进行总结归纳,重点是以示例的方式进行展示. 使用type获取创建对象的类 type(dic ...
- Redis的WEB界面管理工具phpRedisAdmin
下载地址:http://down.admin5.com/php/75024.html 官方网址:https://github.com/ErikDubbelboer/phpRedisAdmin
- spring容器启动过程
1.AbstractApplicationContext的prepareRefresh()方法调用. 2.XmlBeanDefinitionReader的loadBeanDifinitions(Bea ...
- zookeeper系列之二—zookeeper历史
Zookeeper是什么? Zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby的一个开源版本.它是为分布式应用提供一致性服务的软件,提供的功能包括:配置服 ...
- js九宫格的碰撞检测
说来惭愧,我一直以为四四方方的拖拽碰撞检测是一个比较容易的事情,后来试过一次,真是让我耗费了无数的脑细胞,原理其实不难,但是具体做起来可就让我很恶心,这可能跟我驾驭的代码数量有关系,我一般也就写半屏幕 ...
- [转]C# List<T>的详细用法
所属命名空间:System.Collections.Generic publicclassList<T> : IList<T>,ICollection<T>, IE ...
- 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. ...