日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

快速幂、矩阵快速幂、快速乘法

發布時間:2023/11/29 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 快速幂、矩阵快速幂、快速乘法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

快速冪

快速冪是我們經常用到的一種算法,快速冪顧名思義就是快速的冪運算。我們在很多題目中都會遇到冪運算,但是在指數很大的時候,我們如果用for或者是pow就會超時,這時候就用到了快速冪。

快速冪的原理就是,當求b^p的時候,如果p是一個奇數,那么我們就可以把它拆成(b^2)^(p/2)*b,因此每次判斷一下是直接乘還是拆開就可以了。

洛谷模板鏈接:https://www.luogu.org/problemnew/show/P1226

下面是代碼:

#include<bits/stdc++.h> using namespace std; long long b,p,k; void ksm(){long long ans=1,a=b,bb=b,pp=p;while(p){if(p&1) ans=ans*a%k; //判斷要不要拆開p>>=1; //p除以2a=a*a%k;}printf("%lld^%lld mod %lld=%lld",bb,pp,k,ans%k); } int main(){scanf("%lld%lld%lld",&b,&p,&k);ksm();return 0; }

?


矩陣快速冪

矩陣快速冪顧名思義就是把快速冪的整數換成矩陣,要學習矩陣快速冪,就要先知道矩陣的乘法規則。矩陣的乘法規則由下圖所示:

注意:兩個矩陣可以做乘法的條件是矩陣A的大小是N*M,矩陣B的大小是M*K,這樣的兩個矩陣相乘,得到矩陣C的大小是N*K。(通俗的說就是,第一個矩陣的列數等于另一個矩陣的行數)

矩陣的乘法有幾個性質是很重要的,必須記住,不要搞混:①矩陣乘法滿足乘法結合律 ②矩陣乘法滿足乘法分配律(包括左分配律和右分配律,左分配律是:C*(A+B)=CA+CB,右分配律是:(A+B)*C=AC+BC) ③矩陣乘法不滿足乘法交換律(例:AC!=CA)。

矩陣乘法的時間復雜度是O(NMK)的,下面是矩陣乘法的代碼:

?

for(i=1;i<=n;++i)for(j=1;j<=m;++j)for(l=1;l<=k;++l)c[i][l]+=a[i][j]*b[j][l];

?

注意:在做矩陣乘法的時候,最好是按照我上面代碼的循環順序計算,因為如果你改變了循環順序,速度就會變慢,如果你不相信的話可以去試一試,這是因為按照我代碼的順序,在計算一部分值之前,他的原值已經存在緩存中了,這樣的話是比從內存中讀取快的,而改變順序的話,就會從內存中調用,就會變慢了。

學會了矩陣乘法,矩陣快速冪就很輕松了。因為矩陣快速冪和快速冪的區別就在于,一個是整數的次方運算,一個是矩陣的次方運算。但需要注意的是,在矩陣相乘的時候,要存在第三方數組中,這樣才不會影響矩陣的值。

洛谷模板鏈接:https://www.luogu.org/problemnew/show/P3390

下面是AC代碼:

#include<bits/stdc++.h> using namespace std; typedef long long ll; const int M=1000; const ll mod = 1e9+7; ll n,k,a[M][M],b[M][M],c[M][M]; void jz(int x){register int i,j,l;if(x==1){for(i=1;i<=n;++i)for(j=1;j<=n;++j)for(l=1;l<=n;++l)c[i][l]=(c[i][l]+a[i][j]*b[j][l]%mod)%mod;for(i=1;i<=n;++i)for(j=1;j<=n;++j)b[i][j]=c[i][j];memset(c,0,sizeof c);}else{for(i=1;i<=n;++i)for(j=1;j<=n;++j)for(l=1;l<=n;++l)c[i][l]=(c[i][l]+a[i][j]*a[j][l]%mod)%mod;for(i=1;i<=n;++i)for(j=1;j<=n;++j)a[i][j]=c[i][j];memset(c,0,sizeof c); //記住每次要清空 } } void ksm(){while(k){if(k & 1) jz(1);k>>=1;jz(2);} } int main(){register int i,j;scanf("%lld",&n);scanf("%lld",&k);for(i=1;i<=n;++i)for(j=1;j<=n;++j)scanf("%lld",&a[i][j]),b[i][j]=a[i][j];--k; //因為在上一句中,在答案中已經有了矩陣A的一次方 ksm();for(i=1;i<=n;++i){for(j=1;j<=n;++j)printf("%lld ",b[i][j]);printf("\n");}return 0; }

?


?

快速乘法

快速乘法和快速冪的思想差不多,KSM是把a^p的p二進制分解,而快速乘法是把a*b的b分解,一般和KSM配套食用。當KSM%p會超范圍的時候,也就是取模之前就會乘爆,就要用到快速乘法。快速乘法就是把乘法改成加法,這樣一步一步的取模,就不會出現乘爆的問題了。

因為沒有找到例題,這里直接附上代碼:

typedef long long ll; ll ksmul(ll x,ll y,int p){ //x*y%pll ans=0;while(y){if(y & 1) ans=(ans+y)%p;y>>=1;x=(x+x)%p;}return ans; }

?

轉載于:https://www.cnblogs.com/Glacier-elk/p/9489655.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的快速幂、矩阵快速幂、快速乘法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。