【數學】【數論】快速冪
阿新 • • 發佈:2018-12-20
寫在前面:
記錄了個人的學習過程,同時方便複習
- 快速冪
在求解同餘方程時,常常會遇到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 }