快速幂取模算法模板

在Miller Rabbin测试素数,就用到了快速幂取模的思想。这里总结下。
求a^b%c(这就是著名的RSA公钥的加密方法),当a,b很大时,直接求解这个问题不太可能 
算法1:利用公式a*b%c=((a%c)*b)%c,这样每一步都进行这种处理,这就解决了a^b可能太大存不下的问题,但这个算法的时间复杂度依然没有得到优化
代码如下:

int modexp_simple(int a,int b,int n)
{
int ret = 1;
while (b--)
{
ret = a * ret % n;
}
return ret;
}

算法2:另一种算法利用了二分的思想,可以达到O(logn)。
可以把b按二进制展开为:b = p(n)*2^n  +  p(n-1)*2^(n-1)  +…+   p(1)*2  +  p(0)
其中p(i) (0<=i<=n)为 0 或 1

这样 a^b =  a^ (p(n)*2^n  +  p(n-1)*2^(n-1)  +...+  p(1)*2  +  p(0))
               =  a^(p(n)*2^n)  *  a^(p(n-1)*2^(n-1))  *...*  a^(p(1)*2)  *  a^p(0)
对于p(i)=0的情况, a^(p(i) * 2^(i-1) ) =  a^0  =  1,不用处理
我们要考虑的仅仅是p(i)=1的情况
化简:a^(2^i)  = a^(2^(i-1)  * 2) = (  a^(  p(i)  *  2^(i-1)  )  )^2
(这里很重要!!具体请参阅秦九韶算法:http://baike.baidu.com/view/1431260.htm
利用这一点,我们可以递推地算出所有的a^(2^i)
当然由算法1的结论,我们加上取模运算:
a^(2^i)%c = ( (a^(2^(i-1))%c) * a^(2^(i-1)))  %c

于是再把所有满足p(i)=1的a^(2^i)%c按照算法1乘起来再%c就是结果 即二进制扫描从最高位一直扫描到最低位

实例代码:递归

//计算a^bmodn
int modexp_recursion(int a,int b,int n)
{
int t = 1;

if (b == 0)
return 1;

if (b == 1)
return a%n;

t = modexp_recursion(a, b>>1, n);

t = t*t % n;

if (b&0x1)
{
t = t*a % n;
}

return t;
}

实例代码2:非递归优化 

#include <iostream>
using namespace std;

//计算a^bmodn
int modexp(int a,int b,int n)
{
int ret=1;
int tmp=a;
while(b)
{
//基数存在
if(b&0x1) ret=ret*tmp%n;
tmp=tmp*tmp%n;
b>>=1;
}
return ret;
}

int main()
{
cout<<modexp(2,10,3)<<endl;
return 0;
}

另外的一种写法3:

long long bigmod(long long a,long long b,long long m)
{
    long long d,t;
    d=1;
    t=a;
    while (b>0)
    {
        if (b%2==1)
            d=(d*t)%m;
        b/=2;
        t=(t*t)%m;
    }

    return d;
}


参考文章来源:Reait  Home(http://www.reait.com/blog.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/382019.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学脚本的忠告——我觉得语言大多这样了

1.不要看到别人的回复第一句话就说&#xff1a;给个代码吧&#xff01;你应该想想为什么。当你自己想 出来再参考别人的提示&#xff0c;你就知道自己和别人思路的差异。2.初学者请不要看太多太多的书那会误人子弟的&#xff0c;先找本系统的学&#xff0c;很多人用了很久 都是…

hdu 1317——XYZZY

http://blog.csdn.net/dongshimou/article/details/35984917

UVA10843——Anne\'s game

Lily: “Chantarelle was part of my exotic phase.” Buffy: “It’s nice. It’s a mushroom.” Lily: “It is? That’s really embarrassing.” Buffy: “Well, it’s an exotic mushroom, if that’s any comfort.” Joss Whedon, "Anne". A little girl whose…

在kali Linux中搭建DVWA

1、 由于所发教程前几步没有实现&#xff0c;故直接打开浏览器输入localhost/1.php&#xff0c;打开后即为所要页面 2、用cd /var/www/html 命令进入apache web目录 3、用wget https&#xff1a;//github.com/ethicalhack3r/DVWA/archive/master.zip (注意&#xff1a;ethic…

数组名与函数的结合使用注意项

数组名即数组的首地址&#xff0c;故数组名属于指针变量&#xff0c;在定义函数使数组名作为形参时&#xff0c;要把对应的参数定义为指针变量。因为数组没有特定的使其读入停止的标志&#xff0c;因此还要有确定数组长度的参数&#xff0c;即用户自己输入数组长度。 代码如下…

uva 10883——Supermean

Do you know how to compute the mean (or average) of n numbers? Well, thats not good enough for me. I want the supermean! "Whats a supermean," you ask? Ill tell you. List the n given numbers in non-decreasing order. Now compute the average of ea…

-又见GCD -- ACM解决方法

有三个正整数a,b,c(0<a,b,c<10^6)&#xff0c;其中c不等于b。若a和c的最大公约数为b&#xff0c;现已知a和b&#xff0c;求满足条件的最小的c。 Input 第一行输入一个n&#xff0c;表示有n组测试数据&#xff0c;接下来的n行&#xff0c;每行输入两个正整数a,b。 Ou…

Cake -- ACM解决方法

一次生日Party可能有p人或者q人参加,现准备有一个大蛋糕.问最少要将蛋糕切成多少块(每块大小不一定相等),才能使p人或者q人出席的任何一种情况,都能平均将蛋糕分食. Input 每行有两个数p和q. Output 输出最少要将蛋糕切成多少块. Sample Input 2 3 Sample Output 4 …

vi 的 使用

vi &#xff08;Linux下的文本编辑器&#xff09; a 在光标后添加文本A 在本行行末添加文本i 在光标前插入文本I 在本行开始插入文本o 在光标下插入新行O 在光标上插入新行dd 删除光标所在行 &#xff08;2dd即删除此下的两行&#xff0c;3dd以此类推&#xff09;p 粘贴&#…

卡特兰数的性质及其应用扩展

问题描述&#xff1a;卡塔兰数&#xff0c;是组合数学中一个常出现在各种计数问题中出现的数列。输入一个整数n&#xff0c;计算h(n)。其递归式如下&#xff1a;h(n) h(0)*h(n-1)h(1)*h(n-2) ... h(n-1)h(0) (其中n>2&#xff0c;h(0) h(1) 1) 该递推关系的解为&…

Linux 部分常用命令

屏幕切换 Ctrl Alt F1 &#xff5e; F6 切换为图形界面Ctrl Alt F7 切换为字符界面 基本命令 ifconfig 查看ip &#xff08;Windows中是 ipconfig &#xff09;halt 关机 &#xff08;或 shutdown -h now&#xff09;reboot 重启tab 自动补全Ctrl U 清空至行首Ctrl K 清空至…

汉诺塔V - ACM解决方法

Problem Description 用1,2,...,n表示n个盘子&#xff0c;称为1号盘&#xff0c;2号盘,...。号数大盘子就大。经典的汉诺塔问题经常作为一个递归的经典例题存在。可能有人并不知道汉诺塔问题的典故。汉诺塔来源于印度传说的一个故事&#xff0c;上帝创造世界时作了三根金刚石柱…

uva 10692——Huge Mods

题目大意&#xff1a;给定第一个数M&#xff0c;后面有n的数&#xff0c;求解a[1]^a[2]^a[3]^…..%m的解 思路&#xff1a;开始的时候并不知道从哪里下手&#xff0c;一开始收到前面某题除4的印象&#xff0c;然后一直对4取余&#xff0c;知道a[1],计算后发现那一套只适用于求解…

笨小熊 -- ACM解决方法

描述 笨小熊的词汇量很小&#xff0c;所以每次做英语选择题的时候都很头疼。但是他找到了一种方法&#xff0c;经试验证明&#xff0c;用这种方法去选择选项的时候选对的几率非常大&#xff01; 这种方法的具体描述如下&#xff1a;假设maxn是单词中出现次数最多的字母的出现…

uva 10710——Chinese Shuffle

题目大意&#xff1a;给定一个数n&#xff0c;然后洗牌n-1次问是否能回到初始状态&#xff0c;能回到则是jimmy—number&#xff0c;否则不是&#xff0c;具体怎么洗的&#xff0c;题中的图已经能够说明的很清楚&#xff0c;在此不再赘述&#xff01;思路&#xff1a;开始设了这…

括号配对问题 -- ACM解决方法

括号配对问题 &#xff08;栈的使用&#xff09;描述 现在&#xff0c;有一行括号序列&#xff0c;请你检查这行括号是否配对。 输入 第一行输入一个数N&#xff08;0<N<100&#xff09;,表示有N组测试数据。后面的N行输入多组输入数据&#xff0c;每组输入数据都是一…

中国剩余定理即孙子定理的五种解法

加深一下理解&#xff0c;找了点纯数学的资料&#xff08;老者善学&#xff0c;尤老骥伏枥&#xff0c;况乎我也&#xff09;&#xff1a;“中国剩余定理”是公元5-6世纪、我国南北朝时期的一部著名算术著作《孙子算经》中的一个“物不知数”的解法问题&#xff1a;今有物不知其…

阶乘因式分解(一) -- ACM解决方案

阶乘因式分解&#xff08;一&#xff09;描述 给定两个数m,n,其中m是一个素数。将n&#xff08;0<n<10000&#xff09;的阶乘分解质因数&#xff0c;求其中有多少个m。 输入 第一行是一个整数s&#xff08;0<s<100)&#xff0c;表示测试数据的组数随后的s行, 每…

uva 11490 ——Just Another Problem

题意&#xff1a;刚开始并没有看懂&#xff0c;耐着性子硬读下去&#xff0c;才勉强弄懂大意&#xff0c;英语也要加强训练啊&#xff01;题目是说你有s行c列士兵&#xff0c;然后带着他们去打仗&#xff0c;为了虚张声势&#xff0c;在士兵的中间缺了两个边长为r的洞&#xff…

uva 11728——Alternate Task

题意&#xff1a;及其无聊的一道题目&#xff0c;以前做STl专题的时候&#xff0c;曾经做过一道求一个数的所有约数之和的题目&#xff0c;该题和那道题刚好相反&#xff0c;是给你一个数的约数之和&#xff0c;问这个数可能是多少&#xff01;题目&#xff1a;还能咋办&#x…