1. 程式人生 > >【數學】【數論】快速冪

【數學】【數論】快速冪

寫在前面:

  記錄了個人的學習過程,同時方便複習

 

  • 快速冪

  在求解同餘方程時,常常會遇到ab%c的問題

  顯然,對ab的計算耗費空間很大,甚至會資料溢位

  但是根據模運算的分配律,就可以對這個步驟進行簡化

(在[◹]對算術基本定理的研究中提到過)

  先引入小學學習的一種方法:ab == a*a*a*...*a  (b個a連乘)

  那麼ab%c

  == (a*a*a*...*a)%c  (b個a連乘)

  == (a%c*a%c*a%c*...*a%c)%c  (b個a%c連乘)

  == {[(a%c*a%c*a%c*...*a%c)%c(b/2個a%c連乘)

* (a%c*a%c*a%c*...*a%c)%c(b/2個a%c連乘)]%c * (b/2) * (a%c)}%c

  == {[(a%c)2%c]*[(a%c)2%c]*...*[(a%c)2%c]%c(b/2個(a%c)2連乘) * (b/2) * (a%c)}%c

  == ...

 

  這樣不斷地消去b,對ab的過程量取模,就又保證了資料不溢位

 

  從二進位制的角度看更好理解

  就是從小到大對這個數對應的二進位制位逐個乘上,然後在步驟之間取模

注:b&1即b%2==1,b>>=1即1b/=2

  程式碼:

C++:

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 int x,y,z;
 6 
 7 int Pony_FE(int a,int b,int c)
 8 {
 9     int ans=1;
10     a%=c;
11     while(b!=0)
12     {
13         if(b&1) ans=(ans*a)%c;
14         b>>=1;
15         a=(a*a)%c;
16     }
17     return ans;
18 }
19 20 int main(int argc,char *argv[],char *enc[]) 21 { 22 scanf("%d%d%d",&x,&y,&z); 23 printf("%d\n",Pony_FE(x,y,z)); 24 25 return 0; 26 }

Java:

 1 import java.io.*;
 2 import java.util.*;
 3 
 4 class pony{
 5 
 6     static int x,y,z;
 7 
 8     static int Pony_FE(int a,int b,int c)
 9     {
10         int ans=1;
11         a%=c;
12         while(b!=0)
13         {
14             if(b%2==1) ans=(ans*a)%c;
15             b>>=1;
16             a=(a*a)%c;
17         }
18         return ans;
19     }
20 
21     public static void main(String[] args) throws Exception {
22         
23         Scanner cin=new Scanner(System.in);
24         
25         x=cin.nextInt();
26         y=cin.nextInt();
27         z=cin.nextInt();
28 
29         System.out.println(Pony_FE(x,y,z));
30     }
31 }

  當然還有遞迴寫法的

C++:

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 int x,y,z;
 6 
 7 int Pony_FE(int a,int b,int c)
 8 {
 9     if(!b) return 1;
10     int res=Pony_FE(a,b/2,c);
11     res=(res*res)%c;
12     if(b&1) res=(res*a)%c;
13     return res;
14 }
15 
16 int main(int argc,char *argv[],char *enc[])
17 {
18     scanf("%d%d%d",&x,&y,&z);
19     printf("%d\n",Pony_FE(x,y,z));
20     
21     return 0;
22 }

Java:

 1 import java.io.*;
 2 import java.util.*;
 3 
 4 class pony{
 5 
 6     static int x,y,z;
 7 
 8     static int Pony_FE(int a,int b,int c)
 9     {
10         if(b==0) return 1;
11         int res=Pony_FE(a,b/2,c);
12         res=(res*res)%c;
13         if(b%2==1) res=(res*a)%c;
14         return res;
15     }
16 
17     public static void main(String[] args) throws Exception {
18         
19         Scanner cin=new Scanner(System.in);
20         
21         x=cin.nextInt();
22         y=cin.nextInt();
23         z=cin.nextInt();
24 
25         System.out.println(Pony_FE(x,y,z));
26     }
27 }