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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

关于快速幂

發布時間:2023/12/19 综合教程 17 生活家
生活随笔 收集整理的這篇文章主要介紹了 关于快速幂 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

快速冪是個快速計算冪次的算法,原理很簡單:

a^b=a*a*a*a*a*......*a (b個a 相乘) 如果直接計算要做 b-1 次乘法。

可以利用冪運算的性質: a^b=(a^c)*(a^d)=a^(c+d) 其中b=c+d

如果把b平均分為兩份,每份的數量為c=d=b/2, a^c和a^d的值一樣,就可以重復利用。

這樣分一次就只要做 b/2-1+1=b/2次的乘法,若b為奇數,則要做b/2+1次乘法,于是乘法的次數就大大減少,

這樣重復分幾次后,原式的值就能很快地算出來。

用遞歸的代碼:

1 int QuickPow(int a,int b)
2 {
3      if (b==1) return a;
4      if (b&1) return QuickPow(a,b-1)*a;   //b為奇數
5      return QuickPow(a,b/2);
6 }

非遞歸:

 1 int QucikPow(int a,int b)
 2 {
 3     int ans=1;
 4     while (b)
 5     {
 6          if (b&1) ans=ans*a;
 7          b=b>>1;
 8          a=a*a;
 9      }
10     return ans;
11 }

注意事項:

1.用遞歸的方法會好理解點,但如果b很大的話遞歸會爆棧。

2. 函數返回值可能會溢出,如題目要求可利用模運算規則:(a*b)%m=(a%m*b%m)%m

3. 就算取模了,算法中有乘法操作的地方也還可能會溢出,這就要用快速冪的變式:

快速加法: a*b=a*(b/2)+a*(b/2)

(a+b)%m=(a%m+b%m)%m

這樣就不會溢出了。(還是在tyvj p2043 發現的,下面附上AC代碼)

 1 #include <stdio.h>
 2 unsigned long long p,m,n;
 3 unsigned long long ans=1;
 4 inline unsigned long long quickadd(unsigned long long a,unsigned long long m)
 5 {
 6    unsigned long long ans=0;
 7    while (a)
 8    {
 9        if (a&1) ans=(ans+m)%p;
10        a=a>>1;
11        m=(m*2)%p;
12    }
13    return ans;
14 }
15 void quick(unsigned long long n)
16 {
17   while (n)
18   {
19       if (n&1) ans=(quickadd(ans,m))%p;
20       n=n>>1;
21       m=(quickadd(m,m))%p;
22   }
23 }
24 
25 int main()
26 {
27   scanf("%I64d%I64d%I64d",&n,&m,&p);
28   ans=m%p;
29   m=m-1;
30   m=m%p;
31   quick(n-1);
32   printf("%I64d\n",ans);
33 }

總結

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

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