欧拉余数定理通解,求A的B次幂模C的值( A^B mod C)
#欧拉余数定理算法
对于 A^B mod C
(网上的算法基本上不见考虑 A ,C 不互质的情况,显然是残缺的)
1.如果 A ,C 不互质(互质:两个数做因式分解,公共因子只有1)
通过约分使得新的C1与A互质,如果C1与A不互质,则重复此步骤。
记录的约数积Y 和商S积
2 如果 A 大于 C ,则A = A %C
3 求C的欧拉函数值euler
4 如果B不小于euler, B=B%euler
5 计算 e=A^B ,此时A,B已经较小了
6 A^B mod C =(e*S %C)*Y
举个例子 :15 ^6mod12 = 9
A=15
B=6
C=12
一,15,12有约数3:
A=15
B=B-1=5
C=12/3=4
Y=3
S=15/3=5
二 A>C:
A=A%C=15%4=3
三 求C的欧拉函数值:
euler(4)=2
四 :
B=B%euler=5/2=1
五 计算 :
e=A^B =3 ^ 1=3
六 :
A^B mod C =(e*S %C )*Y = 3* 5%4*3=15%4*3=3*3=9
代码
public class Mod {public static int powerMod(int a,int pow,int n) {int factor=coprime(a,n);int multiplier=1;int quotient=1;int cya=a;int cyn=n;int cypow=pow;while(factor>0&&cypow>1) {multiplier*=factor;quotient*=cya/factor;cyn/=factor;cypow--;factor=coprime(cya,cyn);}if(cya>cyn) {cya%=cyn;}int euler = eulerFunction(cyn);if(cypow>euler&&euler>0) {cypow%=euler;}int ret=1;if(cya==0) {ret=0;}else if(cypow==0) {ret=1;}while(cypow>0) {ret*=cya;cypow--;}return (quotient*ret%cyn)*multiplier;}public static int eulerFunction(int n) {if(isPrimeNumber(n)) {return n-1;}int count=0;for(int i=1;i<n;i++) {if(coprime(i,n)<0) {count+=1;}}return count;}public static int coprime(int a,int b) {int min = Mod.min(a,b);for(int i=2;i<=min;i++) {if(a%i==0) {if(b%i==0) {return i;}}}return -1; }public static <E extends Comparable<E>> E min(E ... pars) {Objects.requireNonNull(pars);if(pars.length==0) {throw new NullPointerException();}E min=pars[0];for(int i=1;i<pars.length;i++) {if(min.compareTo(pars[i])>0) {min=pars[i];}}return min; }
}
测试 欧拉函数
for(int i=1;i<21;i++) {System.out.println(i+"->"+eulerFunction(i));}
1->0
2->1
3->2
4->2
5->4
6->2
7->6
8->4
9->6
10->4
11->10
12->4
13->12
14->6
15->8
16->8
17->16
18->6
19->18
20->8
测试模方法
手工单个检验无疑是不可取得,所以使用BigInteger 进行结果检验。
A C 的值一定要取小点,原因在下文。
for(int i=1;i<10;i++) {int a=(int) (Math.random()*20);int b=(int) (Math.random()*1000+1);int c=(int) (Math.random()*20+1);System.out.println(a+" ^ "+b+" mod "+c);System.out.print("powerMod "+powerMod(a,b,c));BigInteger big=BigInteger.valueOf(a);System.out.println(" vs " +" big "+big.modPow(BigInteger.valueOf(b), BigInteger.valueOf(c)));}
13 ^ 214 mod 2
powerMod 1 vs big 1
12 ^ 178 mod 16
powerMod 0 vs big 0
6 ^ 73 mod 16
powerMod 0 vs big 0
3 ^ 890 mod 13
powerMod 9 vs big 9
6 ^ 572 mod 17
powerMod -5 vs big 13
8 ^ 805 mod 2
powerMod 0 vs big 0
15 ^ 665 mod 18
powerMod 9 vs big 9
10 ^ 290 mod 2
powerMod 0 vs big 0
17 ^ 149 mod 6
powerMod 5 vs big 5
很容易发现有个异常值:
6 ^ 572 mod 17
powerMod -5 vs big 13
不难想到原因定是整型溢出。
可以推敲一下。
euler(17)=16
572%16=12
6 ^ 12 = 3 ^ 24
int=2^31-1< 2 ^32
3 ^ 24 /2 ^ 32=(3/2) ^ 24 / (2 ^ 8 )
3/2=1.5>2 ^ (1/2)=1.414
(3/2) ^ 24 / (2 ^ 8 ) > ( 2 ^ (1/2) ) ^ 24 / (2 ^ 8 ) =2 ^ 12 / 2 ^8=16
至少大了16倍,所以必然出错。
解决方案:
将int 包装成 BigInteger 即可。
增加本算法与BigInteger.modPow()时间效率的对比,不禁感叹源码的神奇。
欧拉余数定理通解,求A的B次幂模C的值( A^B mod C)相关推荐
- 欧拉函数:求小于等于n且与n互质的数的个数
求小于等于n且与n互质的数的个数 互质穷举法 互质:两个数互质代表两者最大公约数为1 最大公约数求法:辗转相除法,最小公倍数:较大值除以最大公约数乘以较小值 辗转相除法: 较大的数a取模较小的数b,得 ...
- 【2021牛客寒假第五场】C-比武招亲(下)欧拉降幂+多项式求逆预处理伯努利数计算等幂求和
[2021牛客寒假第五场]C-比武招亲(下)欧拉降幂+多项式求逆预处理伯努利数计算等幂求和 前置技能 题意 思路 Code(715MS) 传送门: https://ac.nowcoder.com/ac ...
- 欧拉函数(求与n互质的数的个数)
求解与n(1-n-1)互质的质因子的个数 解析:(转) 定义:对于正整数n,φ(n)是小于或等于n的正整数中,与n互质的数的数目. 例如:φ(8)=4,因为1,3,5,7均和8互质. 性质:1.若p是 ...
- 欧拉筛 筛法求素数 及其例题 时间复杂度O(n)
埃式筛法尽管不错,但是确实做了许多无用功,某个数可能会被重复的筛好几次,欧拉筛解决了这个方法,下面为代码: 注意理解if(i%prim[j]==0) break; 大佬讲的不错的博客,我就不做复读机了 ...
- 欧拉线性筛法求素数(顺便实现欧拉函数的求值)
标签:欧拉筛法 素数 欧拉函数 phi 我们先来看一下最经典的埃拉特斯特尼筛法.时间复杂度为O(n loglog n) int ans[MAXN]; void Prime(int n) { ...
- 欧拉线性筛 求n的最小正因数的个数
由算术基本定理可得: 任何一个大于1的N的自然数,如果N不为质数,可以被分解成有限个质数的乘机,即 n=(p1a1)*(p2a2)(p3a3)*--*(pnan),在这里(p1<p2<p3 ...
- 利用欧拉四面体公式求任意三棱锥的体积
OA=20.81,OB=23.9,OB=14.98,AB=15.38,BC=18.03,CA=25.37 将a=OA,b=OB,c=OC,l=AB,m=BC,n=CA 带入下式计算,利用三个棱长求体 ...
- Relatives POJ - 2407(不打表的欧拉函数 单求)
Relatives POJ - 2407 题目链接:https://vjudge.net/problem/POJ-2407#author=0 题目: 给定n是一个正整数,有多少正整数小于n是n的相对素 ...
- spoj26246 Strange But Easy(欧拉筛选法求素数)
用php提交超时,改为c++ #include <cstdio> #include <vector> #include <cstring>using namespa ...
最新文章
- 2022-2028年中国丁二烯橡胶行业市场规模研究及前瞻分析报告
- ibatis 配置参数解析
- 吃西餐的吴大师略懂《赤壁》
- Oracle中用一个序列给两个表创建主键自增功能的后果
- springboot使用webjars引入jquery
- SQL优化的若干原则
- c++ STL:队列queue、优先队列priority queue 的使用
- 取某个单元格的值_vba中如何进行单元格复制,Copy方法使用介绍,一定要学
- Python轻量级WEB框架web.py之操作数据库
- Python+OpenCV:仿射变换和透射变换
- python---之suplot和suplots的区别
- 【SQL Server】入门教程-基础篇(二)
- android studio 2.3.3 最新 中文 汉化包 韩梦飞沙 安卓工作室 美化包
- Linux共享文件夹
- EDEM基础操作步骤
- 一道求极值的三角函数题
- vue3 web项目引入高拍仪
- 跳马周游c++_C++——跳马问题(广搜)
- 京东商智-指数转换/指数还原
- linux 删除tmp文件夹,Linux下tmp文件夹的文件自动删除的问题(转)