完美...

指针搞死我了

///
/// Author: zball
/// No rights reserved
/// (Creative Commons CC0)
///
#include <cstdio>
#include <malloc.h>
#include <cstring>
#define maxn 10000100
#define qm 1000000007
namespace matrix_mem{
int *mem_cur,mem_start[maxn];
inline void init(){
memset(mem_start,0,sizeof(mem_start));
mem_cur=mem_start;
}
inline int* get(int size){
int* p=mem_cur;
mem_cur=mem_cur+size;
return p;
}
// inline void freea();
}
/*inline void matrix_mem::freea(){
free(mem_cur);
}*/
inline int fitQm(int n){
if(n>=qm) return n-qm; return n;
}
inline int fitQm1(int n){
if(n<0) return n+qm; return n;
}
namespace matrices{
int *mats[10][9];
#define compute_offset(n) (((n+sx)<<bxl)+sy)
struct submatrix{
//submatrix is a simple matrix package
int *t,sx,sy,xl,bxl;
inline submatrix(){}
inline submatrix(int* t,int sx,int sy,int xl,int bxl):t(t),sx(sx),sy(sy),xl(xl),bxl(bxl){}//for xl==yl case
inline void set(int* _t,int _sx,int _sy,int _xl,int _bxl){
t=_t,sx=_sx,sy=_sy,xl=_xl,bxl=_bxl;
}
inline submatrix(const submatrix& p,int _sx,int _sy){
t=p.t;
sx=_sx+p.sx;
sy=_sy+p.sy;
xl=p.xl-1;
bxl=p.bxl;
}
inline int* operator[](int n){
return t+compute_offset(n);//this operator returns a pointer points to the correct position
}
inline void makeIdentity(){
int l=1<<xl;
for(int i=0;i<l;++i) for(int j=0;j<l;++j) (*this)[i][j]=0;
for(int i=0;i<l;++i) (*this)[i][i]=1;
}
};
typedef submatrix sm;
sm curs[10][9];
inline void init(){
for(int i=1;i<10;++i){
for(int j=0;j<9;++j){
mats[i][j]=matrix_mem::get(1<<(i<<1));
// if(mats[i][j]==NULL) printf("ERROR %d %d\n",i,j);
curs[i][j].set(mats[i][j],0,0,i,i);
}
}
}
inline int fitQm(int n){
if(n>=qm) return n-qm; return n;
}
inline int fitQm1(int n){
if(n<0) return n+qm; return n;
}
inline void add(sm& c,sm& a,sm& b){//b and c should be at the same size!!!IMPORTANT.
int l=1<<b.xl;
for(int i=0;i<l;++i) for(int j=0;j<l;++j) c[i][j]=fitQm(a[i][j]+b[i][j]);
}
inline void sub(sm& c,sm& a,sm& b){//b and c should be at the same size!!!IMPORTANT.
int l=1<<b.xl;
for(int i=0;i<l;++i) for(int j=0;j<l;++j) c[i][j]=fitQm1(a[i][j]-b[i][j]);
}
inline void transfer(sm& a,sm& b){
int l=1<<b.xl;
for(int i=0;i<l;++i) for(int j=0;j<l;++j) a[i][j]=b[i][j];
}
inline void transferPartial(sm& a,sm& b,int x,int y){
//transfer b to a[x][y] -> ...
submatrix reunify(a.t,a.sx+x,a.sy+y,b.xl,a.bxl);
//just to a coordinate convertion
transfer(reunify,b);
}
int q;
#define naive_threshold 4
inline void multiply_limb(sm& out,sm& a,sm& b){//2x2 , 4x4 or 8x8 limbs
int l=1<<a.xl;
for(int i=0;i<l;++i) for(int j=0;j<l;++j) out[i][j]=0;
for(int k=0;k<l;++k) for(int i=0;i<l;++i) for(int j=0;j<l;++j) out[i][j]=(out[i][j]+(long long)a[i][k]*b[k][j])%qm;
}
inline void print(sm p){
for(int i=0,_=1<<p.xl;i<_;++i){
for(int j=0;j<_;++j) printf("%d ",p[i][j]);
putchar('\n');
}
}
#define ntmp curs[lm]
#define mult multiply_strassen
#define half(_t,a,x,y) _t.set(a.t,a.sx+(x),a.sy+(y),a.xl-1,a.bxl)
void multiply_strassen(sm c,sm a,sm b){
if(a.xl<=naive_threshold) multiply_limb(c,a,b); else {
int l=1<<a.xl;
for(int i=0;i<l;++i) for(int j=0;j<l;++j) c[i][j]=0;
int lm=a.xl-1;
submatrix A11(a,0,0),A12(a,0,1<<lm),A21(a,1<<lm,0),A22(a,1<<lm,1<<lm);
submatrix B11(b,0,0),B12(b,0,1<<lm),B21(b,1<<lm,0),B22(b,1<<lm,1<<lm);
submatrix C11(c,0,0),C12(c,0,1<<lm),C21(c,1<<lm,0),C22(c,1<<lm,1<<lm);
sub(ntmp[0],B12,B22);
mult(ntmp[1],A11,ntmp[0]);
add(ntmp[0],A11,A12);
mult(ntmp[2],ntmp[0],B22);
add(ntmp[0],A21,A22);
mult(ntmp[3],ntmp[0],B11);
sub(ntmp[0],B21,B11);
mult(ntmp[4],A22,ntmp[0]);
add(ntmp[0],A11,A22);
add(ntmp[8],B11,B22);
mult(ntmp[5],ntmp[0],ntmp[8]);
sub(ntmp[0],A12,A22);
add(ntmp[8],B21,B22);
mult(ntmp[6],ntmp[0],ntmp[8]);
sub(ntmp[0],A11,A21);
add(ntmp[8],B11,B12);
mult(ntmp[7],ntmp[0],ntmp[8]);
//M1...M7 are stored in ntmp[1]...ntmp[7].
/*
M1 = A11(B12 - B22)
M2 = (A11 + A12)B22
M3 = (A21 + A22)B11
M4 = A22(B21 - B11)
M5 = (A11 + A22)(B11 + B22)
M6 = (A12 - A22)(B21 + B22)
M7 = (A11 - A21)(B11 + B12)
C11 = M5 + M4 - M2 + M6
C12 = M1 + M2
C21 = M3 + M4
C22 = M5 + M1 - M3 - M7
*/
/* for(int i=1;i<=7;++i){
printf("\nM%d====================\n",i);
print(ntmp[i]);
}*/
add(ntmp[0],ntmp[5],ntmp[4]);
sub(ntmp[8],ntmp[0],ntmp[2]);
add(C11,ntmp[8],ntmp[6]);
add(C12,ntmp[1],ntmp[2]);
add(C21,ntmp[3],ntmp[4]);
add(ntmp[0],ntmp[5],ntmp[1]);
sub(ntmp[8],ntmp[0],ntmp[3]);
sub(C22,ntmp[8],ntmp[7]);
}
}
}
using namespace matrices;
int main(){
matrix_mem::init();
matrices::init();
submatrix a(matrix_mem::get(1<<10),0,0,5,5);
submatrix b(matrix_mem::get(1<<10),0,0,5,5);
submatrix c(matrix_mem::get(1<<10),0,0,5,5);
// submatrix c(a,2,1);
a.makeIdentity();
b.makeIdentity();
mult(c,a,b);
for(int i=0;i<32;++i){
for(int j=0;j<32;++j){
printf("%d ",c[i][j]);
}
putchar('\n');
}
return 0;
}

把strassen乘法调出来了...的更多相关文章

  1. 第四章 分治策略 4.2 矩阵乘法的Strassen算法

    package chap04_Divide_And_Conquer; import static org.junit.Assert.*; import java.util.Arrays; import ...

  2. 4-2.矩阵乘法的Strassen算法详解

    题目描述 请编程实现矩阵乘法,并考虑当矩阵规模较大时的优化方法. 思路分析 根据wikipedia上的介绍:两个矩阵的乘法仅当第一个矩阵B的列数和另一个矩阵A的行数相等时才能定义.如A是m×n矩阵和B ...

  3. 《算法导论》——矩阵乘法的Strassen算法

    前言: 很多朋友看到我写的<算法导论>系列,可能会觉得云里雾里,不知所云.这里我再次说明,本系列博文时配合<算法导论>一书,给出该书涉及的算法的c++实现.请结合<算法导 ...

  4. 算法导论-矩阵乘法-strassen算法

    目录 1.矩阵相乘的朴素算法 2.矩阵相乘的strassen算法 3.完整测试代码c++ 4.性能分析 5.参考资料 内容 1.矩阵相乘的朴素算法 T(n) = Θ(n3) 朴素矩阵相乘算法,思想明了 ...

  5. 整数快速乘法/快速幂+矩阵快速幂+Strassen算法

    快速幂算法可以说是ACM一类竞赛中必不可少,并且也是非常基础的一类算法,鉴于我一直学的比较零散,所以今天用这个帖子总结一下 快速乘法通常有两类应用:一.整数的运算,计算(a*b) mod c  二.矩 ...

  6. Strassen优化矩阵乘法(复杂度O(n^lg7))

    按照算法导论写的 还没有测试复杂度到底怎么样 不过这个真的很卡内存,挖个坑,以后写空间优化 还有Matthew Anderson, Siddharth Barman写了一个关于矩阵乘法的论文 < ...

  7. Strassen矩阵乘法之思考

    可不可以有另外的划分小矩阵的方法? A*B=C A/B分成n*m个矩阵 可看成一个多元方程. Ci,k = Ai,j * Bjk 每一个Ci,k看成方程的一个未知数 每一个小式子:对于A或B同一列/行 ...

  8. 关于strassen矩阵乘法的矩阵大小不是2^k的形式时,时间复杂度是否还是比朴素算法好的看法

    原来是n,找到大于等于n且是2^k形式的数m.n*n的矩阵补全为m*m的矩阵,原来的矩阵放在最左上方,其它位置的值为0.朴素方法:n^3现在:m^2.8即m/n需小于e^(3/2.8)=2.919才能 ...

  9. Conquer and Divide经典例子之Strassen算法解决大型矩阵的相乘

    在通过汉诺塔问题理解递归的精髓中我讲解了怎么把一个复杂的问题一步步recursively划分了成简单显而易见的小问题.其实这个解决问题的思路就是算法中常用的divide and conquer, 这篇 ...

随机推荐

  1. jquery特效收藏

    js网址收藏: 懒人图库:www.lanrentuku.com 懒人之家:http://www.lanrenzhijia.com/jquery/list_5_2.html 1.UI下载:http:// ...

  2. VIM自动补全插件 - YouCompleteMe--"大神级vim补全插件"

    VIM自动补全插件 - YouCompleteMe 序言 vim 之所以被称为编辑器之神多半归功于其丰富的可DIY的灵活插件功能,( 例如vim下的这款神级般的代码补全插件YouCompleteMe) ...

  3. NGUI 圆形头像遮罩

    NGUI 圆形头像遮罩 列表,求助 http://tieba.baidu.com/p/3961444508

  4. centos 7.0安装花生壳

    没有wget 先下载get  命令 yum -y install wget 下载位置/usr/local/src 解压目录 /usr/local/bin/phddns-2.0.6.x86_64 1.下 ...

  5. 【转】 详解Kafka生产者Producer配置

    粘贴一下这个配置,与我自己的程序做对比,看看能不能完善我的异步带代码:   -----------------------------------------    详解Kafka生产者Produce ...

  6. Linux jdk1.7安装与 jdk1.6卸载

    昨天安装zookeeper时需要java环境,也就是安装jdk    安装完jdk1.7后,配置好环境变量, vim ~/.bashrc       JAVA_HOME=安装路径 export PAT ...

  7. JavaScript基础整理(2)

    接下来的重点是函数.我们知道函数是特殊的对象. 函数作用域和声明提前.JavaScript中没有块级作用域,只有函数作用域:变量在声明它们的函数体以及这个函数体嵌套的任意 函数体内都要定义. func ...

  8. 该不该用inline-block取代float? inline和float的区别?

    该不该用inline-block取代float? 请看这篇文章引用: jtyjty99999的博客 让块级元素 水平排列的通常方式是float, 但是float可能会带来很多意外的问题 可以考虑用in ...

  9. regsvr32的使用

    注册器是: DllRegisterServer 命令就是: regsvr32 不是regsrv32.

  10. .NET逻辑分层架构总结

    一.基础知识准备: 1.层的原则: (1)每一层以接口方式供上层调用. (2)上层只能调用下层. (3)依赖分为松散交互和严格交互两种. 2.业务逻辑分类: (1)应用逻辑. (2)领域逻辑. 3.采 ...