矩阵

来源:互联网 发布:unity3d怎么导入fbx 编辑:程序博客网 时间:2024/06/05 07:00

定义矩阵乘法:C=AB

如果Amn矩阵,Bnp矩阵,那么C是一个mp矩阵。

其中Cik=nk=1AijBjk,如:

[142536]135246=[1+6+154+15+302+8+188+20+36]=[22492864]

矩阵乘法满足结合律,不满足交换律。

单位矩阵In

In=100010001

矩阵乘法及快速幂:

struct Matrix{    int m[M][M];    Matrix(){        memset(m,0,sizeof(m));    }    void Init(){//初始化单位矩阵         for(int i=1;i<=n;i++)            m[i][i]=1;    }    Matrix operator *(const Matrix &a)const{        Matrix res;        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++){                if(!m[i][j])continue;                for(int k=1;k<=n;k++)                    res.m[i][k]+=m[i][j]*a.m[j][k];            }        return res;    }};Matrix Pow(Matrix x,int t){    Matrix res;    res.Init();    while(t){        if(t&1)res=res*x;        x=x*x;        t>>=1;    }    return res;}

POJ3070 Fibonacci

Task:

求斐波那契数列第n位取模P的值。(P=10000,n<=1000000000)

Solution:
首先直接循环是O(n)的。

考虑矩阵快速幂:

[f[n]f[n1]]=[1110][f[n1]f[n2]]

[f[n]f[n1]]=[1110]n1[f[1]f[0]]=[1110]n1[10]An1B

于是将这个矩阵A快速幂,就可以在O(logn)时间内解决这道题了。

#include<stdio.h>#include<string.h>#define M 5#define P 10000const int n=2;struct Matrix{    int m[M][M];    Matrix(){        memset(m,0,sizeof(m));    }    void Init(){//初始化单位矩阵         for(int i=1;i<=n;i++)            m[i][i]=1;    }    Matrix operator *(const Matrix &a)const{        Matrix res;        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++){                if(!m[i][j])continue;                for(int k=1;k<=n;k++)                    res.m[i][k]=(res.m[i][k]+m[i][j]*a.m[j][k])%P;            }        return res;    }};Matrix Pow(Matrix x,int t){    Matrix res;    res.Init();    while(t){        if(t&1)res=res*x;        x=x*x;        t>>=1;    }    return res;}int main(){    Matrix B;    B.m[1][1]=1;B.m[2][1]=0;    while(1){        int d;        scanf("%d",&d);        if(d==-1)break;        if(!d){            puts("0");            continue;        }        Matrix A;        A.m[1][1]=A.m[1][2]=A.m[2][1]=1;A.m[2][2]=0;        A=Pow(A,d-1);        A=A*B;        printf("%d\n",A.m[1][1]);    }    return 0;}
0 0