那啥,,矩阵乘法,矩阵快速幂模板

来源:互联网 发布:怎么查询端口是否开启 编辑:程序博客网 时间:2024/06/05 15:16

这个是乘法加剪枝的。

Mat operator * (Mat a, Mat b) {    Mat c;    memset(c.mat, 0, sizeof(c.mat));    int i, j, k;    for(k = 0; k < n; ++k) {        for(i = 0; i < n; ++i) {            if(a.mat[i][k] <= 0)  continue;   //不要小看这里的剪枝,cpu运算乘法的效率并不是想像的那么理想(加法的运算效率高于乘法,比如Strassen矩阵乘法)            for(j = 0; j < n; ++j) {                if(b.mat[k][j] <= 0)    continue;    //剪枝                c.mat[i][j] += a.mat[i][k] * b.mat[k][j];            }        }    }    return c;}

******************************

这个是自己刚刚改的剪枝,,,,快了30ms,,,

赶脚差不多啦。可能自己写的用得顺手。

用的时候记得改“16”。

struct node mul(node x,node y){    int i,j,k;    node z;    memset(z.a,0,sizeof(z.a));    for(i=0;i<16;i++)    {        for(j=0;j<16;j++)        {            for(k=0;k<16;k++)                if(!x.a[i][k]||!y.a[k][j]) continue;                else z.a[i][j]+=x.a[i][k]*y.a[k][j]%m;            z.a[i][j]%=m;        }    }    return z;}


然后这个是连乘的。

Mat operator ^ (Mat a, int k) {    Mat c;    int i, j;    for(i = 0; i < n; ++i)        for(j = 0; j < n; ++j)            c.mat[i][j] = (i == j);    //初始化为单位矩阵    for(; k; k >>= 1) {        if(k&1) c = c*a;        a = a*a;    }    return c;}

***************************

警觉没有快速幂的模板(自己用过的),赶紧来一发。


#include <cstdlib>#include <cstring>#include <cstdio>#include <iostream> using namespace std;int N;struct matrix{       int a[3][3];}origin,res;matrix multiply(matrix x,matrix y){       matrix temp;       memset(temp.a,0,sizeof(temp.a));       for(int i=0;i<3;i++)       {               for(int j=0;j<3;j++)               {                       for(int k=0;k<3;k++)                       {                               temp.a[i][j]+=x.a[i][k]*y.a[k][j];                       }               }       }       return temp;}void init(){     printf("随机数组如下:\n");     for(int i=0;i<3;i++)     {             for(int j=0;j<3;j++)             {                     origin.a[i][j]=rand()%10;                     printf("%8d",origin.a[i][j]);             }             printf("\n");     }     printf("\n");     memset(res.a,0,sizeof(res.a));     res.a[0][0]=res.a[1][1]=res.a[2][2]=1;                  //将res.a初始化为单位矩阵 }void calc(int n){     while(n)     {             if(n&1)                    res=multiply(res,origin);             n>>=1;             origin=multiply(origin,origin);     }     printf("%d次幂结果如下:\n",n);     for(int i=0;i<3;i++)     {             for(int j=0;j<3;j++)                     printf("%8d",res.a[i][j]);             printf("\n");     }     printf("\n");}int main(){    while(cin>>N)    {            init();            calc(N);    }    return 0;}

嗯,,,其实快速幂的精髓就是这个,然后我不会运算符重载= =,所以这里每次的乘法要用函数代替啦,其他一样一样。

while(N) {                if(N&1)                       res=res*A;                n>>=1;                A=A*A; }


0 0
原创粉丝点击