快速冪就是快速計算m^n
「快」主要體現在它把複雜度從一般迴圈計算的o(n)級別降低到了o(logn)級別。
一般情況下,m^n=m*m*m*…*m,實現就是用一般的迴圈計算來實現。
而快速冪的想法是將m^n表示成m^(2^a1+2^a2…),2^a1+2^a2+…=n;
我們現在假設n=10;
一般想法就是將m乘以10次,用簡單的for迴圈就能實現。
這個是快速冪的**
int qmul(int m,int n)
return res;
}
快速冪想法就是m^10=m^(2^3+2^1)=m^(2^3)*m^(2^1)=m^8*m^2
在**中,m=m*m讓m以指數倍的速度增長著。
m一開始不變,在迴圈時,m的值依次為 m^2 m^4 m^8 m^16 …那0
n=10時,我們只需要篩選出我們需要的,即m^2 , m^8
而 if(n%2==1) 就是篩選條件。n%2==1等價於n的二進位制末位是1
10的二進位制表示是1010,很明顯為1項才是我們需要的
n>>1的作用是去掉二進位制最後一位,即1010變成了101
當n的末位為1時,m就會正好變到了我們想要的值,這個可以自己手動執行看看。
矩陣快速冪其實就是把m換成矩陣,然後自己寫一下矩陣乘法就行。
最近在刷藍橋杯上的題目,那個遞推求值就可以用矩陣快速冪做。
題目如下:
已知遞推公式:
f(n, 1)=f(n-1, 2) + 2f(n-3, 1) + 5,
f(n, 2)=f(n-1, 1) + 3f(n-3, 1) + 2f(n-3, 2) + 3.
初始值為:f(1, 1)=2, f(1, 2)=3, f(2, 1)=1, f(2, 2)=4, f(3, 1)=6, f(3, 2)=5。
輸入n,輸出f(n, 1)和f(n, 2),由於答案可能很大,你只需要輸出答案除以99999999的餘數。
題目n的取值範圍很大,所以一般的方法肯定會超時,用快速冪降低時間複雜度就很必要。
**如下:
#include
#include
#define n 7
#define mod 99999999
typedef
struct matrixmatrix;
matrix unit=;
matrix base=;
matrix ans=;
matrix mul(matrix a,matrix b)}}
return res;
}matrix qmul(matrix m,long
long
int n)
return res;
}int main()
else
if(n==2)
else
if(n==3)
else
return
0;}
這道題目主要是需要根據題意,得到關於矩陣的遞推方程
f(n,1) 0
...001
0020
5 f(n-
1,1) 0
...0
f(n,2) 0
...010
0032
3 f(n-
1,2) 0
...0
f(n-
1,1) 0
...010
0000
0 f(n-
2,1) 0
...0
f(n-
1,2) 0
...0=0
1000
00 x f(n-
2,2) 0
...0
f(n-
2,1) 0
...000
1000
0 f(n-
3,1) 0
...0
f(n-
2,2) 0
...000
0100
0 f(n-
3,2) 0
...010
...000
0000
110...
0
根據這個方程做題就可以了。 nyoj 301遞推求值 矩陣快速冪的遞推求值
時間限制 1000 ms 記憶體限制 65535 kb 難度 4 描述 給你乙個遞推公式 f x a f x 2 b f x 1 c 並給你f 1 f 2 的值,請求出f n 的值,由於f n 的值可能過大,求出f n 對1000007取模後的值。注意 1對3取模後等於2 輸入 第一行是乙個整數t,...
NYOJ 301 遞推求值(矩陣快速冪)
時間限制 1000 ms 記憶體限制 65535 kb 難度 4 描述 給你乙個遞推公式 f x a f x 2 b f x 1 c 並給你f 1 f 2 的值,請求出f n 的值,由於f n 的值可能過大,求出f n 對1000007取模後的值。注意 1對3取模後等於2 輸入 第一行是乙個整數t,...
NYOJ 301 遞推求值 矩陣快速冪
時間限制 1000 ms 記憶體限制 65535 kb 難度 4 描述 給你乙個遞推公式 f x a f x 2 b f x 1 c 並給你f 1 f 2 的值,請求出f n 的值,由於f n 的值可能過大,求出f n 對1000007取模後的值。注意 1對3取模後等於2 輸入 第一行是乙個整數t,...