快速幂取模
来源:互联网 发布:守望先锋各个性能数据 编辑:程序博客网 时间:2024/06/02 04:18
快速幂取模算法
例如:求a^b % c
ans = ans * a;
这个算法的时间复杂度体现在for循环中,为O(b).这个算法存在着明显的问题,如果a和b过大,很容易就会溢出。
a = a % c; //加上这一句
for(int i = 1;i<=b;i++)
ans = ans * a;
算法3:
for(int i = 1;i<=b;i++)
ans = (ans * a) % c; //这里再取了一次余
这个算法在时间复杂度上没有改进,仍为O(b),不过已经好很多的,但是在c过大的条件下,还是很有可能超时,
算法4:
if(b%2==1)
我们可以看到,当我们令k = (a * a) mod c时,状态已经发生了变化,我们所要求的最终结果即为k^(b/2) mod c而不是原来的a^b mod c,所以我们发现这个过程是可以迭代下去的。当然,对于奇数的情形会多出一项a mod c,所以为了完成迭代。当b是奇数时,我们通过ans = (ans * a) % c来弥补多出来的这一项,此时剩余的部分就可以进行迭代了。
{
if(b % 2 == 1) // 如果b是奇数时
ans = (ans * a) % c;
将上述的代码结构化,也就是写成函数:
int PowerMod(int a, int b, int c)
{
int ans = 1;
a = a % c;
while(b>0)
{
if(b % 2 = = 1) // 如果b是奇数时
ans = (ans * a) % c;
b = b/2;
a = (a * a) % c;
}
return ans;
}
本算法的时间复杂度为O(logb),能在几乎所有的程序设计(竞赛)过程中通过,是目前最常用的算法之一。
例如:求a^b % c
算法1.
int ans = 1;
for(int i = 1;i<=b;i++)ans = ans * a;
ans = ans % c;
这个算法的时间复杂度体现在for循环中,为O(b).这个算法存在着明显的问题,如果a和b过大,很容易就会溢出。
算法2:
int ans = 1; // a^b%c = (a%c)^b%ca = a % c; //加上这一句
for(int i = 1;i<=b;i++)
ans = ans * a;
ans = ans % c;
算法3:
int ans = 1;
a = a % c; //加上这一句for(int i = 1;i<=b;i++)
ans = (ans * a) % c; //这里再取了一次余
ans = ans % c;
这个算法在时间复杂度上没有改进,仍为O(b),不过已经好很多的,但是在c过大的条件下,还是很有可能超时,
快速幂算法依赖于以下明显的公式。
算法4:
int ans = 1;
a = a % c;if(b%2==1)
ans = (ans * a) mod c; //如果是奇数,要多求一步,可以提前算到ans中
k = (a*a) % c; //我们取a^2而不是afor(int i = 1;i<=b/2;i++)
ans = (ans * k) % c;ans = ans % c;
我们可以看到,当我们令k = (a * a) mod c时,状态已经发生了变化,我们所要求的最终结果即为k^(b/2) mod c而不是原来的a^b mod c,所以我们发现这个过程是可以迭代下去的。当然,对于奇数的情形会多出一项a mod c,所以为了完成迭代。当b是奇数时,我们通过ans = (ans * a) % c来弥补多出来的这一项,此时剩余的部分就可以进行迭代了。
形如上式的迭代下去后,当b=0时,所有的因子都已经相乘,算法结束。于是便可以在O(log b)的时间内完成了。
int ans = 1;
a = a % c;
while(b>0){
if(b % 2 == 1) // 如果b是奇数时
ans = (ans * a) % c;
b = b/2;
a = (a * a) % c;
}将上述的代码结构化,也就是写成函数:
int PowerMod(int a, int b, int c)
{
int ans = 1;
a = a % c;
while(b>0)
{
if(b % 2 = = 1) // 如果b是奇数时
ans = (ans * a) % c;
b = b/2;
a = (a * a) % c;
}
return ans;
}
本算法的时间复杂度为O(logb),能在几乎所有的程序设计(竞赛)过程中通过,是目前最常用的算法之一。
0 0
- 快速幂,快速幂取模
- 快速幂 + 快速幂取模
- 快速幂 快速幂取模
- 快速幂 快速幂取模
- 【快速幂】【快速幂取模】
- 快速幂,快速幂取模,矩阵快速幂
- 快速幂取模
- 快速幂取模
- 快速幂取模
- 快速幂取模
- 快速幂取模
- 快速幂取模
- 快速幂取模
- 快速幂取模
- 快速幂取模
- 快速幂取模
- 快速幂取模
- 快速幂取模
- 杭电 2067
- 网页生成工具,图片格式转换,文件夹相关
- hdu2099 整除的尾数
- ORACLE DG 激活 activate database
- HDU 一个人的旅行(Dijkstra)
- 快速幂取模
- 如何解决…has been modified since the precompiled header… was built的问题
- linux 下查看java安装目录
- poj 1276 Cash Machine(多重背包)
- C# OFFICE WORD EXCEL操作
- oracel dg日常管理
- 一个人的旅行——最短路
- tlb与dll文件
- oracel dg failover 切换