题目链接: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. Python 中translate()与replace()区别

    translate函数和replace函数一样,用于替换字符串中的某个部分,但是和replace不同,translate只处理单个字符,而且可以同时进行多个替换.在使用translate函数转换之前, ...

  2. 2015-09-17 001 日志与对话框公用类_public

    using System;using System.Data;using System.Configuration;using System.Linq;using System.Web;using S ...

  3. sql查询某条记录

    select * from (SELECT t.*,ROWNUM AS RN FROM AWARDISSUE_FOOTBALL t ORDER BY ID DESC) WHERE RN=2

  4. iq 格式分析

    po iq {type:1 name:iq xml:"<iq xmlns="jabber:client" to="testhjy@ecouser.net/ ...

  5. 达人眼中的WINCE网络驱动

    实际上在WinCE上开发网络驱动,比如设计一个NIC驱动, 大多数情况,是从XP移植NDIS Miniport驱动(小端口驱动)到WinCE.什么是ndis?Ndis做什么用的? 什么是minipor ...

  6. Android 网格布局 计算器

    <GridLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&quo ...

  7. CoreData 与 SQLite 比较

    CoreData.framework : iOS中提供了对原始SQLite数据库API访问的封装,通过这个framework来管理数据缓存和持久数据要比使用SQL语句操作SQLite数据库简单和方便许 ...

  8. UVA 11795 七 Mega Man's Mission

    七 Mega Man's Mission Time Limit:1000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Subm ...

  9. [3D] 基本概念

    [3D] 基本概念 环境光:对场景中所有的对象都提供了固定不变的照明.点光源:是从一个点发出的光.灯泡就可以理解为点光源.聚光源:正如它的的名字一样,是有方向和强弱的,电筒就是典型的聚光源. 方向光: ...

  10. VBA中自定义类和事件的(伪)注册

    想了解一下VBA中自定义类和事件,以及注册事件处理程序的方法. 折腾了大半天,觉得这样的方式实在称不上“注册”,所以加一个“伪”字.纯粹是瞎试,原理也还没有摸透.先留着,有时间再接着摸. 做以下尝试: ...