Matrix Power Series—-矩陣乘法(二分)

來源:互聯網
上載者:User

題目:http://poj.org/problem?id=3233

A+A^2+A^3……+A^k

如果k是偶數的話,原式=(I+A^k/2)(A+A^2……A^k/2)。

如果k是奇數的話,原式=(1+A^(k/2+1))(A+A^2……+A^k/2)+A^(k/2+1)。

我是用數組直接實現的,比較麻煩,速度比較慢,1000+ms。

下面是My Code:

#include <stdio.h>int m,n,k;int a[30][30];int ans[30][30],s[30][30],I[30][30];void init(int x[30][30]){  for(int i=0;i<n;i++)    for(int j=0;j<n;j++)     x[i][j]=0;  for(int i=0;i<n;i++)    for(int j=0;j<n;j++)     if(i==j)     x[i][j]=1;}void add(int x[30][30],int y[30][30],int z[30][30]){    for(int i=0;i<n;i++)      for(int j=0;j<n;j++)      z[i][j]=(x[i][j]+y[i][j])%m;}void multiply(int x[30][30],int y[30][30],int z[30][30]){    for(int i=0;i<n;i++)      for(int j=0;j<n;j++)         z[i][j]=0;    for(int i=0;i<n;i++)      for(int j=0;j<n;j++)        for(int k=0;k<n;k++)         z[i][j]=(z[i][j]+x[i][k]*y[k][j])%m;}void copy(int x[30][30],int y[30][30]){    for(int i=0;i<n;i++)      for(int j=0;j<n;j++)       y[i][j]=x[i][j];}void quickPow(int a[30][30],int z[30][30],int n){    int x[30][30],y[30][30],b[30][30];    copy(a,b);    init(x);  init(z);    while(n>0)    {        if(n%2==1)  multiply(b,x,z);        n=n/2;        copy(z,x);        multiply(b,b,y);        copy(y,b);    }}void solve(int a[30][30],int k){    int b[30][30],c[30][30];    if(k==1)  { copy(a,ans); copy(a,s); return ; }    solve(a,k/2);    if(k%2==0)    {       quickPow(a,b,k/2);       add(I,b,c);       multiply(c,s,ans);       copy(ans,s);    }    else    {        quickPow(a,b,k/2+1);        add(I,b,c);        multiply(c,s,ans);        copy(ans,s);        add(b,s,ans);        copy(ans,s);    }}int main(){    //freopen("D:\\a.txt","r",stdin);    scanf("%d%d%d",&n,&k,&m);    for(int i=0;i<n;i++)     for(int j=0;j<n;j++)      scanf("%d",&a[i][j]);     init(s);  init(ans); init(I);     solve(a,k);     for(int i=0;i<n;i++)     {         for(int j=0;j<n;j++)         printf("%d ",ans[i][j]);         printf("\n");     }}

後來看了一些比較快的代碼,200-ms,他們使用結構體實現的,都知道結構體可以作為函數的傳回值,操作簡單,速度相對就快了。

下面是看到的代碼:

原文地址http://www.cnblogs.com/forever4444/archive/2009/05/12/1454736.html

代碼:

#include <iostream>#define MAX 33using namespace std;typedef struct node{    int matirx[MAX][MAX];}Matrix;Matrix a,sa,unit;int n,k,m;void Init(){    int i,j;    for(i=0;i<n;i++)        for(j=0;j<n;j++)        {            scanf("%d",&a.matirx[i][j]);            a.matirx[i][j]%=m;   //初始化要先%m            unit.matirx[i][j]=(i==j);  //如果i==j那麼矩陣中此值就是1,否則為0,就是主對角線是1的單位矩陣        }}Matrix Add(Matrix a,Matrix b)  //矩陣加法{    Matrix c;    int i,j;    for(i=0;i<n;i++)        for(j=0;j<n;j++)        {            c.matirx[i][j]=a.matirx[i][j]+b.matirx[i][j];            c.matirx[i][j]%=m;   //加的時候也要%m        }    return c;}Matrix Mul(Matrix a,Matrix b)  //矩陣乘法{    Matrix c;    int i,j,k;    for(i=0;i<n;i++)        for(j=0;j<n;j++)        {            c.matirx[i][j]=0;  //初始化矩陣c            for(k=0;k<n;k++)                c.matirx[i][j]+=a.matirx[i][k]*b.matirx[k][j];            c.matirx[i][j]%=m;  //計算乘法的時候也要%m        }    return c;}Matrix Cal(int exp)   //矩陣冪{    Matrix p,q;    p=a;  //p是初始矩陣    q=unit;  //q是單位矩陣    while(exp!=1)    {        if(exp&1)  //要求得冪是奇數        {            exp--;            q=Mul(p,q);        }         else    //要求的冪是偶數        {            exp>>=1;  //相當於除2            p=Mul(p,p);        }    }    p=Mul(p,q);    return p;}Matrix MatrixSum(int k){    if(k==1)  //做到最底層就將矩陣a返回就好        return a;    Matrix temp,tnow;    temp=MatrixSum(k/2);    if(k&1)  //如果k是奇數    {        tnow=Cal(k/2+1);        temp=Add(temp,Mul(temp,tnow));        temp=Add(tnow,temp);    }      else    //如果k是偶數    {        tnow=Cal(k/2);        temp=Add(temp,Mul(temp,tnow));    }    return temp;}int main(){    int i,j;    while(scanf("%d%d%d",&n,&k,&m)!=EOF)    {        Init();        sa=MatrixSum(k);        for(i=0;i<n;i++)        {            for(j=0;j<n-1;j++)            {                printf("%d ",sa.matirx[i][j]%m);            }            printf("%d\n",sa.matirx[i][n-1]%m);        }    }    return 0;

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.