題目資訊如圖所示:
剛開始思考,以為難點是在大數相乘,寫了乙個字串傳參的大數函式(模擬簡單的乘法),但是發現沒法取模,以及迴圈次數太多了,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 該方法依賴於這樣乙個事實 即轉化為矩陣求...