快速冪:
方法一::
首先快速冪有幾個公式:
1.(a^b)mod c=( a mod c)^b mod c;
(ab) mod c=[(a mod c)*( b mod c)] mod c; (積的取餘等於取餘的積取餘)
快速冪演算法依賴於一下兩個公式:
a^b mod c=((a²)^(b/2)) mod c , b是偶數
a^b mod c=((a²)(b/2)*a) mod c ,b是奇數
有了上述兩個公式,我們可以得出一下結論:
1.如果b是偶數,我們可以記k=a²modc,那麼(k)^(b/2)mod c 就可以了.
2.如果b是奇數,我們也可以記k=a²modc,那麼((k)^(b/2)mod c就可以了
所以有了最終的演算法:快速冪演算法(log b):
int ans=1;
a=a%c;
while(b>0)
將上述**結構化,也就是寫成函式:
int powermod(int a,int b,int c)
return ans;
}
方法二::
用位運算來實現:
1.b&1(取b的二進位制最低位(即第0位) 判斷b是否為奇數,是則為1
)
2.b>>1(去掉b的二進位制最低位(即第0位)
)
所以**實現為:
#include#includeusing namespace std;
int pow3(int x,int n)
} cout<>=1;
while(n!=0)
return result;
} int main()
然後了解一下矩陣相乘原理
:兩個相乘是要一行和一列對應乘,那麼矩陣乘法是需要a的行數與b的列數相等的,矩陣快速冪只會用到方陣(n*n)矩陣快速冪是用來求解遞推式的,所以第一步先要列出遞推式:f(n)=f(n-1)+f(n-2)
第二步是建立矩陣遞推式,找到轉移矩陣:
這裡就是個矩陣乘法等式左邊:1*f(n-1)+1*f(n-2)=f(n);1*f(n-1)+0*f(n-2)=f(n-1);
所以這裡相乘就是矩陣n-1次相乘,然後輸出第一行第二個元素,也就是a[0][1]
這裡可以練習一下poj 3070,其實就是矩陣快速冪的模板題
然後給一些簡單的遞推式:
1.f(n)=a*f(n-1)+b*f(n-2)+c;(a,b,c是常數)
2.f(n)=c^n-f(n-1) ;(c是常數)
快速乘:
問題:
求 (a*b) % m 的值,其中 a,b,m 是1到10^18。
如果直接乘的話,因為a和b還有m都很大,那麼會溢位long long,所以需要一些方法。
樸素的想法是用陣列模擬高精度,但是比較麻煩。
還有更好的方法:
求乘法的列豎式,
那麼如果變成二進位制的話 10101 × 1011 = 10101*1+10101*2^1*1+10101*2^2*0+10101*2^3*1;
這樣**如下:
long long multi(long long a,long long b,long long m)
return ans;
}
快速乘 快速冪(矩陣快速冪)
當mod乙個大數p的時候,還有進行乘法的時候可能會爆long long的時候,就用快速乘或者快速冪。參考 先上模板 快速乘 ll multi ll a,ll b,ll m return ans 快速冪 ll pow mod ll a,ll b,ll m return res 快速乘 快速冪 hdu題...
斐波那契(矩陣快速冪)
斐波那契數列,即fib n fib n 1 fib n 2 fib n fib n 1 fib n 2 fib n fib n 1 fi b n 2 就這麼乙個數列,顯然可以直接遞推求解,時間複雜度o n o n o n 似乎沒什麼問題。然後就遇到了這個,n nn的取值範圍最大是2 1 09 2 t...
矩陣快速冪求斐波那契數列
求數a aa的n nn次冪,可以採用二分法進行快速計算,即 a n a cdot a n為偶數 a cdot a cdot a n為奇數 end right.an a n a a a cdot a cdot a cdot a cdots a a cdot a cdot a cdot a 2 cdot...