快速求出 a^k mod p 的结果,时间复杂度为 O(logk),其中 a,p,k 为10的9次方。
暴力求解:
res =1;for(int i =1; i <= k; i++){
res = res * a mod p;}// 时间复杂度 O(k);
2、核心原理——反复平方法
原理:
求解问题是 a^k mod p 。
方法是将 a^k 拆成若干项相乘的形式,即把 k 化成二进制形式,变成2的幂次相加。
推导过程:反复平方法求解过程
举例:
算法步骤:
res =1;while(k !=0){if((k &1)==1)){
res = res * a % p;}
k >>=1;
a =(a * a)% p;return res;}
3、快速幂求逆元
乘法逆元定义:
若整数 b,m互质,并且对于任意的整数 a,如果满足 b|a,则存在一个整数 x,使得a/b ≡ a×x(modm),则称 x 为 b 的模 m 乘法逆元,记为 b^−1(modm)。b 存在乘法逆元的充要条件是 b 与模数 m 互质。当模数 m为质数时,b^(m−2) 即为 b 的乘法逆元。
性质:
求解问题与转化为:
举例:
无解条件:
b 为 p 的倍数,即两个数并不能做到互质,则 b * x ≡ 0 (mod p),无法满足余1的条件。
二、Java、C语言模板实现
// java 模板// 快速幂求解staticlongqmi(long a,long k,long p){// 快速幂求解long res =1;while(k !=0){if((k &1)==1){
res = res*a % p;}
k >>=1;
a = a * a % p;}return res;}// 快速幂求解staticlongqmi(long a,long k,long p){// 快速幂求解long res =1;while(k !=0){if((k &1)==1){
res = res*a % p;}
k >>=1;
a = a * a % p;}return res;}if(a % p !=0){// 本题中只保证了p为质数,没保证ap互质// 此处判定两者a p是否能整除,如果整除,则代表不互质System.out.println(result);}else{System.out.println("impossible");}
// C++ 模板,由yxc实现
求 m^k mod p,时间复杂度 O(logk)。
intqmi(int m,int k,int p){int res =1% p, t = m;while(k){if(k&1) res = res * t % p;
t = t * t % p;
k >>=1;}return res;}
三、例题题解
// java题解实现importjava.util.*;importjava.io.*;publicclassMain{staticlongqmi(long a,long k,long p){// 快速幂的求解long res =1;// 结果存储while(k !=0){// 判断是否已经移位完毕,变成了0if((k &1)==1){// 取出最后一位,如果等于1,则代表这一位的二进制可以用来构建幂次值
res = res * a % p;// a代表的就是不同幂次,相乘即指数相加,k等于指数相加}
k >>=1;// 右移一位
a =(a * a)% p;// 构成ak的幂次,每一个都是上一个幂次的 平方 + mod p}return res;}publicstaticvoidmain(String[] args)throwsIOException{BufferedReader in =newBufferedReader(newInputStreamReader(System.in));String str1 = in.readLine();int n =Integer.parseInt(str1);for(int i =0; i < n; i++){String[] str2 = in.readLine().split(" ");int a =Integer.parseInt(str2[0]);int k =Integer.parseInt(str2[1]);int p =Integer.parseInt(str2[2]);System.out.println(qmi(a, k, p));}}}
importjava.util.*;importjava.io.*;publicclassMain{staticlongqmi(long a,long k,long p){// 快速幂求解long res =1;while(k !=0){if((k &1)==1){
res = res*a % p;}
k >>=1;
a = a * a % p;}return res;}publicstaticvoidmain(String[] args)throwsIOException{BufferedReader in =newBufferedReader(newInputStreamReader(System.in));String str1 = in.readLine();int n =Integer.parseInt(str1);for(int i =0; i < n; i++){String[] str2 = in.readLine().split(" ");long a =Integer.parseInt(str2[0]);long p =Integer.parseInt(str2[1]);long result =qmi(a, p -2, p);// 之所以是 p - 2 是费马定理得到的if(a % p !=0){// 本题中只保证了p为质数,没保证ap互质// 此处判定两者a p是否能整除,如果整除,则代表不互质System.out.println(result);}else{System.out.println("impossible");}}}}