1. 程式人生 > >矩陣快速冪 ——(遞推表示式)

矩陣快速冪 ——(遞推表示式)

 矩陣快速冪

 首先知道矩陣 

     矩陣(Matrix)是一個按照長方陣列排列的複數實數集合;

     矩陣乘法:

定義:設A為  m×p  的矩陣,B為  p×n  的矩陣,那麼稱  m×n  的矩陣C為矩陣AB的乘積,記作  C=A×B ,其中矩陣C中的第  i  行第  j  列元素可以表示為:

知道矩陣乘法之後,比如菲波那切數列就是一個遞推式,     F(n)=F(n-1)+F(n-2); 因為矩陣乘法,所以 設 矩陣 A為                    矩陣 B 為                    則  A*B  則為    F(n)=        F(n-1)*1+F(n-2)*1
因為我們需要的矩陣為  A*B  的矩陣為                                   所以倒推到 B 矩陣 ,則 B矩陣是    , 所以 F(n) 的矩陣為  初始矩陣   *   (B^(n-2))   n>=3; 所得到的矩陣  A[0][0]  就是F(n) 的值,時間複雜度優化的地方就是在冪指數的那部分快速冪,節約了時間。 所以關鍵就在於  從 遞推式構造矩陣  比如:
這個構造出來的矩陣就是
       自己可以寫出這個矩陣,就明白了;下面給一個簡單的題目,練練手。                                                                                                               

給一個簡單的練習題:   點選開啟連結

#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <bitset>
#include <vector>
#include <iostream>
#include <algorithm>
#include <stdlib.h>


using namespace std;
typedef long long LL;
const int INF=2e9+1e8;
const int MOD=1000007;
const int MAX_SIZE=1005;
const int MM=3;


LL f1,f2,a,b,c,n;


struct Mat
{
    LL maze[MM][MM];
    void set_empty()
    {
        memset(maze,0,sizeof(maze));
    }
};
Mat unit_Mat=
{
    1,0,0,
    0,1,0,
    0,0,1
};   //  定義一個單位矩陣,任何一個矩陣 乘以 單位矩陣,其值等於本身;
Mat operator *(Mat a,Mat b)  // 過載運算子  * //  定義兩個矩陣的乘法,根據矩陣乘法的定義來寫
{
    Mat c;
    c.set_empty();  // 一定要設定為空。清零陣列;不然後面加等一個數會有垃圾值
    LL i,j,k;
    for(i=0; i<MM; i++)
    {
        for(j=0; j<MM; j++)
        {
            for(k=0; k<MM; k++)
            {
                c.maze[i][j]+=a.maze[i][k] * b.maze[k][j];
                c.maze[i][j] %= MOD;
            }
        }
    }
    return c;
}
Mat operator^(Mat a,LL N)  //  優化時間的就在此處,
//  類似與一般的int 數字的快速冪求值,思想是一樣的。不懂可百度快速冪。
{
    Mat c=unit_Mat;
    while(N)
    {
        if(N&1) c=a*c;
        a=a*a;
        N>>=1;
    }
    return c;
}
void solve()
{
    Mat A,B;
    B.set_empty();
    A.set_empty();
    B.maze[0][0]=b,B.maze[1][0]=a,B.maze[2][0]=c;
    B.maze[0][1]=B.maze[2][2]=1;
    B=B^(n-2);
    A.maze[0][0]=f2,A.maze[0][1]=f1,A.maze[0][2]=1;
    LL ans=0;
    Mat C=A*B;
    printf("%lld\n",(C.maze[0][0]+MOD)%MOD);
}
int main()
{
    int times;
    scanf("%d",&times);
    while(times--)
    {
        scanf("%lld %lld %lld %lld %lld %lld",&f1,&f2,&a,&b,&c,&n);
        if(n == 1)
            printf("%lld\n",(f1+MOD)%MOD);
        else if(n == 2)
            printf("%lld\n",(f2+MOD)%MOD);
        else solve();  // 其上位特判 因為公式的定義域是  n>=3;
    }
    return 0;
}


相關推薦

矩陣快速 ——表示式

 矩陣快速冪  首先知道矩陣       矩陣(Matrix)是一個按照長方陣列排列的複數或實數集合;      矩陣乘法: 定義:設A為  m×p  的矩陣,B為  p×n  的矩陣,那麼稱  m×n  的矩陣C為矩陣A與B的乘積,記作  C=A×B ,其中矩陣C中

Queuing矩陣快速and模板

【題目來源】:https://vjudge.net/problem/HDU-2604 【題意】 f,m分別是female與male的縮寫,假設有一個佇列裡面是這些字母縮寫,長度為L,那麼共有2^L種,如果含有fmf或者fff這種子佇列的佇列被稱為0佇列,其餘

POJ3070 Fibonacci矩陣快速加速【模板題】

題目連結:傳送門 題目大意:   求斐波那契數列第n項F(n)。   (F(0) = 0, F(1) = 1, 0 ≤ n ≤ 109) 思路:   用矩陣乘法加速遞推。 演算法競賽進階指南的模板: #include <iostream> #include &l

洛谷P1357 花園狀態壓縮 + 矩陣快速加速

題目連結:傳送門 題目: 題目描述 小L有一座環形花園,沿花園的順時針方向,他把各個花圃編號為1~N(2<=N<=10^15)。他的環形花園每天都會換一個新花樣,但他的花園都不外乎一個規則,任意相鄰M(2<=M<=5,M<=N)個花圃中有不超過K(1&

矩陣快速共軛函式

題目連結:https://cn.vjudge.net/contest/261339#problem/A 具體思路:一開始看到這個題,覺得用快速冪就能很簡單的求出來,結果發現,要是想用快速冪的話,每次計算必然會損失一定的精度,並且取餘的時候必須進行強制轉換,所以這個方法絕對不行。 然後就開

HDU 5950 - Recursive sequence - [矩陣快速加速][2016ACM/ICPC亞洲區瀋陽站 Problem C]

題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=5950 Farmer John likes to play mathematics games with his N cows. Recently, they are attracted by recursive

矩陣快速優化式 例:斐波那契數列

首先是一點基礎知識: ① 矩陣相乘的規則:矩陣與矩陣相乘 第一個矩陣的列數必須等於第二個矩陣的行數 假如第一個是m*n的矩陣 第二個是n*p的矩 陣則結果就是m*p的矩陣且得出來的矩陣中元素具有

Recursive sequence 矩陣快速公式

1. 通常首先能用矩陣快速冪優化的遞推型別是f[n]=5f[n-3]+6f[n-2]+2f[n-1]+n^2+n+8之類的也就是說遞推是線性遞推且f[n-i]前面的係數是常數,可以含有與n有關的多項式,也可以含有常數的這種遞推2.比如以下fn=2fn−2+fn−1+n4通常左

矩陣快速裸,模板

題目來源:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1137 【題意】 中文題意不在敘述,只是讓求一個矩陣的乘法而

矩陣快速共軛函式兩種

題目連結:https://cn.vjudge.net/contest/261339#problem/B AC1:ans= x(n)+y(n)*sqrt(6),所以,ans=x(n)+y(n)*sqrt(6)+(x(n)-y(n)*sqrt(6))-(x(n)-y(n)*sqrt(6))=2*

cf 450b 矩陣快速數論取模 一大坑點啊

sent double res nta note follow efi ted containe Jzzhu has invented a kind of sequences, they meet the following property: You are giv

矩陣快速 hdu1575

 矩陣快速冪 和一般的整數快速冪 是非常相似的 首先會以下 一般的快速冪 int pow(int n,int k) { int ans=1; while(k) { if(k&1) ans*=n; k>>

矩陣快速poj 3070

Fibonacci Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 19397  

矩陣快速 模板

#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 2; const int mod = 10000; //矩陣結構體 stru

矩陣快速模版 快速乘 + 快速 + 矩陣快速

矩陣快速冪:首先前置技能:  快速冪 + 矩陣乘法。 1  快速冪 1.1 快速乘法 1.1.1 引用自2009年國家集訓隊論文,駱可強:《論程式底層優化的一些方法與技巧》 (膜膜膜) 可以根據需要換成uLL   (unsigned long long)

矩陣快速構造

構造矩陣 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #incl

矩陣快速以斐波那契數列為例

小 M 玩數列 【問題描述】 小 W 發現了一個神奇的數列: () = ( − 1) + ( − 2) { ≥ 3, (1) = 1, (2) = 1} ,這就是著名的 Fibonacci Se

快速矩陣快速複雜度Olog(n)C++實現

快速冪 快速冪顧名思義,就是快速算某個數的多少次冪。其時間複雜度為 O(log₂N), 與樸素的O(N)相比效率有了極大的提高。 快速冪實現原理 快速冪的原理比較好懂,就是說假如我們求的是3^11,其實比較通用的辦法就是 for 1:11 a*=3; 時間複雜

矩陣快速模板+例題

模板 #include<cstdio> #include<cmath>//pow函式,其實沒啥用 using namespace std; int n;long long k; const int N=pow(10,9)

CCF201409-5拼圖(狀態壓縮DP+矩陣快速) 骨牌覆蓋問題拓展

文章目錄 拼圖 題意: 分析: 拼圖 題意: 分析: 這是hiho1143 && hiho 1151&&1033 骨牌覆蓋 V2的拓展 搜尋