快速幂
写在前面:
记录了个人的学习过程,同时方便复习
- 快速幂
在求解同余方程时,常常会遇到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 }