幂取模
来源:互联网 发布:嗟乎时运不齐命途多舛 编辑:程序博客网 时间:2024/05/16 15:09
求a^b%c的结果,
方法一:
a*b%c = ((a%c)*b)%c;
代码如下:
int work(int a, int b, int c){ int res = 1; for (int i = 0; i < b; i ++) { res = res * a % c; } return res;}
但是这种方法复杂度太高,不适合大数据运算,下面介绍一种更快的方法。
方法二:
b可以表示成二进制的形式,我们用p数组表示相应位权的数值(或二进制数),用2的指数次方表示位权,则
b = p[i]*2^i + p[i-1]*2^(i-1) + p[i-2]*2^(i-2) + ... + p[1]*2^1 + p[0]*2^0
我们知道相邻位置,高位权是低位权的2倍,所以在p[i] === 1的情况下,相邻两位高位是低位的两倍。
a^b = a^( p[i]*2^i + p[i-1]*2^(i-1) + p[i-2]*2^(i-2) + ... + p[1]*2^1 + p[0]*2^0 )
= a^( p[i]*2^i ) * ( a^( p[i-1]*2^(i-1) ) ) * ( a^( p[i-2]*2^( i-2 ) ) )*...*( a^( p[1]*2^1 ) ) * (a^(p[0]*2^0))
有上我们知道表达式相邻两位在p[i] === 1的情况下,高位是低位的平方。
即:a^( p[i]*2^i ) = ( a^( p[i-1]*2^(i-1) ) ) * ( a^( p[i-1]*2^(i-1) ) ) ;
又有上面的表达式我们知道,当p[i] = 0时,a^( p[i]*2^i ) = a ^ 0 = 1;
所以我们只要p[i] = 1的时候,表达式乘以a^( p[i]*2^i )
我们得到下面的代码:
int mod_exp(int a, int b, int c) a^b%c{ int res, t; res = 1 % c; t = a % c; while (b) { if (b & 1) { res = res * t % c; } t = t * t % c; b >>= 1; } return res;}
因为我们只需要判断相应位置是否为1,我们可以知道二进制数的2^0位的权值为1,则这个是一定是奇数,所以我们可以得到下面的代码:
int mod_exp(int a, int b, int c) a^b%c{ int res, t; res = 1 % c; t = a % c; while (b) { if (b % 2) { res = res * t % c; } t = t * t % c; b /= 2; } return res;}
这个代码易于理解,但是效率略差于上面的代码(其实也没差多少)。
注:位运算是运算器的基本操作,不需要调用累加器,而乘除是比较复杂的,基于加法运算,需要调用累加器!
1 0
- 幂取模
- 幂取模
- 幂取模
- 幂取模
- 幂取模
- 快速幂取模
- 快速幂取模
- 快速幂取模
- 幂取模算法
- 快速幂取模
- 快速幂取模
- 快速幂取模
- 快速幂取模
- 快速幂取模
- 快速幂取模
- 快速幂取模
- 快速幂取模
- 快速幂取模
- QuicklyStudyScala_6
- poj1017 packets
- 流式管理器FlowLayout
- php封装json通信接口
- android 开源组件合集-UI篇
- 幂取模
- 使用HTML5 获取位置
- CMake入门指南
- 【Objective-C】语法(二)带有参数的方法定义
- 【笔记-安全】公私钥、数字证书
- Kinetis MCU GPIO 使用
- 【HEVC学习与研究】1、HEVC概览(1)
- google host 2014
- Android Google In APP Billing 刪除測試物品 android.test.Purchase 筆記