快速冪&矩陣快速冪算法小結

一、爲什莫叫快速冪?矩陣快速冪又是什麼?

快速冪,是根據冪的二進制最後一位0或1來加速進行乘法運算。
例如,在求5^19時,按照普通的求法就是要19個5相乘,這樣雖然可以解出來,但當底數和指數都非常大時,這樣計算的時間會很長,其時間複雜度爲O(n)。但使用快速冪就要快速很多。其計算原理如下(下面底數用a表示,指數用n表示,下面的tmp初始爲a,ans初始爲1):
n=19的二進制是10011,
此時n爲奇數,則ans=ans*tmp;tmp=tmp*tmp;n右移一位;(ans=1*5,tmp=5*5=25)
此時n爲奇數,則ans=ans*tmp;tmp=tmp*tmp;n右移一位;(ans=5*25,tmp=25*25)
此時n爲偶數,則直接tmp=tmp*tmp;n右移一位;(ans=125,tmp=625*625)
此時n爲偶數,則直接tmp=tmp*tmp;n右移一位;(ans=125,tmp=390625*390625)
此時n爲奇數,則ans=ans*tmp;tmp=tmp*tmp;n右移一位;(ans=125*390625*390625,tmp=(390625*390625)^2);
這樣就已經求解成功,僅僅用了5次,大大節省了時間。其時間複雜度爲O(logn)。

矩陣快速冪,顧名思義,就是矩陣做冪運算。其實際和快速冪差不多,只是需要對矩陣的乘法運算去做*運算符的重載。其中有一個重要的矩陣就是單位矩陣,他就相當於數字1一樣,只是它是一個矩陣。例如2x2的單位矩陣爲:
a【0】【0】=1;a【0】【1】=0;
a【1】【0】=0;a【1】【1】=1;

二、快速冪模板

#include<iostream>
using namespace std;

typedef long long ll;
const ll MOD=1000007;

ll quickPow(ll a,ll n){     //求a^n 
    ll tmp=a;
    ll ans=1;
    while(n){
        if(n&1){
            ans=ans*tmp;
        }
        tmp=tmp*tmp;
        n>>=1;
    }
    return ans;
}

int main(){

    //功能需求
    //............ 

    return 0;
}

三、矩陣快速冪模板

#include<iostream>
#include<string.h>
using namespace std;
typedef long long ll;
const int Mod=100000007;

struct maxtri{
    ll v[2][2];
    maxtri (){
        memset(v,0,sizeof(v));      //初始化矩陣 
    }
    maxtri operator *(const maxtri &m){     //重載*運算符 
        maxtri tmp;
        for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
                for(int k=0;k<2;k++){
                    tmp.v[i][j]+=(v[i][k]*m.v[k][j])%Mod;
                }
            } 
        }
        return tmp;
    }
}; 
maxtri M,E,ans;     //M即爲矩陣,E即爲單位矩陣,ans爲解 
void Init(){
    for(int i=0;i<2;i++){
        for(int j=0;j<2;j++){
            if(i==j){
                E.v[i][j]=1;
            }
        }
    }
    M.v[0][0]=2;M.v[0][1]=1;        //具體情況具體值的初始化,這裏是舉例 
    M.v[1][0]=1;M.v[1][1]=0;
}   
maxtri quickPow(maxtri m,ll n){     //核心代碼 
    maxtri tmp=E;
    while(n){
        if(n&1){
            tmp=tmp*m;
        }
        m=m*m;
        n>>=1;
    }
    return tmp;
}

int main(){

    //功能需求
    //............ 

    return 0;
}

四、快速冪及矩陣快速冪的應用

1、快速冪

主要是求指數冪

2、矩陣快速冪

    a.矩陣相乘;
    b.求菲波那切數列的第n項(就是可以從前兩個狀態推到當前狀態,這個關係矩陣的係數還是比較好找的);

這裏寫圖片描述

c.圖論中求對應兩個點長度爲n的路徑數,這是矩陣乘法在圖論中的經典應用,其實就是用到了矩陣乘法的特殊性,因爲矩陣乘法有三重循環,最裏面的一層循環就是在枚舉一個點k,i -> k -> j,那麼從i -> j的路徑數長度爲m的條數就等於i-> k路徑長度爲n的路徑數乘上k -> j路徑長度爲m - n的的路徑條數,枚舉的過程中全加起來,可以看到,這個過程和矩陣乘法的過程是一樣的。矩陣An中的ai,j表示:圖中點i到點j經過n條邊的路徑數。(只要能用矩陣乘法做的事情,一般都要用矩陣快速冪來假設)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章