數列 快速冪

2021-08-28 08:33:10 字數 1565 閱讀 7059

題目資訊如圖所示:

剛開始思考,以為難點是在大數相乘,寫了乙個字串傳參的大數函式(模擬簡單的乘法),但是發現沒法取模,以及迴圈次數太多了,k的值太大。請教了同學,得知使用矩陣快速冪來解題。

矩陣快速冪就是利用a^b次冪,b寫成2進製時,比如,m=2^11,對應的11的2進製位1011,那麼從2^1,2^2,2^4,2^8每個數都是前面乙個數的平方xi(前面的數自己乘自己),那麼,從1011的末尾開始,為1的話,就取過來,做m=m*xi,這樣子就可減少乘的次數。時間複雜度變為o(log2n)。矩陣相乘也是類似的想法。

,ai=(ai-1)*v+(ai-2)*u,最後得出,v,u,1,0組成的二次矩陣的i-2次冪(記為a),即有ai=a2*a[0][0]+a1*a[1][0]。

根據給出的遞推公式,轉為矩陣的冪進行計算是關鍵。

#include#includeusing namespace std;

//構建乙個2*2的矩陣

const int mod=1000000007;

struct mtx

};//定義矩陣相乘函式

mtx mul(mtx m1,mtx m2)

return m3;

}//測試矩陣結果

void output(mtx m)

return ans;

}int main()

更新。。。。。。

返回結果還有一組資料是tle。。。

原來是結構體太慢,然後試著用陣列代替結構體,ac。

**如下。。(不會傳參)用全域性的陣列。。決定該學習下傳參了。。

#include#include#includeusing namespace std;

//構建乙個2*2的矩陣

const __int64 mod=1000000007;

__int64 m3[2][2];

__int64 b[2][2];

//定義矩陣相乘函式

void mul(__int64 m1[2],__int64 m2[2])

}//測試矩陣結果

//矩陣快速冪

void pow(__int64 a[2],__int64 n)

; b[0][0]=1;

b[0][1]=0;

b[1][0]=0;

b[1][1]=1;

while(n)

mul(a,a);

a[0][0]=m3[0][0];

a[0][1]=m3[0][1];

a[1][0]=m3[1][0];

a[1][1]=m3[1][1];

// output(res);

n>>=1;//去掉該數的二進位制最後一位

}}int main()

else if(k==2)

else

return 0;

}

fibonacci數列矩陣快速冪

對於矩陣 1 1 1 0 的n次冪,第一行第二個元素 右上角 的元素即為fibonacci數列的第n項,由此可以根據矩陣的乘法計算fibonacci數列的元素值 矩陣的快速冪利用的也是冪乘的二分法,只不是換成了矩陣的乘法,可以用函式處理。可以定義乙個二維陣列的結構體 typedef struct m...

矩陣快速冪 數列考驗

題面 當 x 10 時,f x x 當 x 10 時,f x a0 f x 1 a1 f x 2 a2 f x 3 a9 f x 10 ai 只能為 0 或 1。現在給定 a0 a9,以及兩個正整數 k m,詢問 f k m 的數值大小 輸出檔案包含多組測試用例,每組測試用例格式如下 第一行給定兩個...

fibonacci 數列的快速冪求法

fibonacci數列的經典解法,即遞迴解法,如下 int fib int n 是十分簡潔,但有乙個問題,即重複求解子問題,複雜度以 n 的指數方式遞增。改進的做法是避免掉重複計算,複雜度可優化到o n 如下 int fib int n return sum 該方法依賴於這樣乙個事實 即轉化為矩陣求...