`
lianxiangbus
  • 浏览: 527587 次
文章分类
社区版块
存档分类
最新评论

快速幂取模

 
阅读更多
原文链接:http://apps.hi.baidu.com/share/detail/18926841
快速幂取模
求a^b%c(这就是著名的RSA公钥的加密方法)
当a,b很大时,直接求解这个问题不太可能
你能想到哪些优化呢?
算法1:直观上,也许最容易想到的是利用a*b%c=((a%c)*b)%c,这样每一步都进行这种处理,这就解决了a^b可能太大存不下的问题,但这个算法的时间复杂度依然是O(n),根本没有得到优化。当b很大时运行时间会很长
算法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^(p(i)*2(i-1)))^2
利用这一点,我们可以递推地算出所有的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就是结果

示例:
3^6%7=3^(2^2)*3^(2^1)%7
=((3^(2^1))^2%7)*(3^1*3^1%7)
=(((3^1*3^1%7)%7)^2%7*2%7)%7
=(4*2)%7
=8%7
=1

当然算法可以进一步改进,比如二进制的每一位不必存起来,可以边求边用
经改进后代码如下:(输入a,k,m,求a^k%m)

long f(long a,long k,long m)
{
long b=1;
while(k>=1)
{
if(k%2==1) b=a*b%m;
a=a*a%m;
k=k/2;
}
return b;
}

例题

D: Raising Modulo Numbers


Time Limit: 1000 ms Case Time Limit: 1000 ms Memory Limit: 30000 KB
Submit: 24 Accepted: 7

Description

People are different. Some secretly read magazines full of interesting girls' pictures, others create an A-bomb in their cellar, others like using Windows, and some like difficult mathematical games. Latest marketing research shows, that this market segment was so far underestimated and that there is lack of such games. This kind of game was thus included into the KOKODáKH. The rules follow:

Each player chooses two numbers Ai and Bi and writes them on a slip of paper. Others cannot see the numbers. In a given moment all players show their numbers to the others. The goal is to determine the sum of all expressions AiBifrom all players including oneself and determine the remainder after division by a given number M. The winner is the one who first determines the correct result. According to the players' experience it is possible to increase the difficulty by choosing higher numbers.

You should write a program that calculates the result and is able to find out who won the game.

Input

The input consists of Z assignments. The number of them is given by the single positive integer Z appearing on the first line of input. Then the assignements follow. Each assignement begins with line containing an integer M (1 <= M <= 45000). The sum will be divided by this number. Next line contains number of players H (1 <= H <= 45000). Next exactly H lines follow. On each line, there are exactly two numbers Ai and Bi separated by space. Both numbers cannot be equal zero at the same time.

Output

For each assingnement there is the only one line of output. On this line, there is a number, the result of expression

(A1B1+A2B2+ ... +AHBH)mod M.

Sample Input

3
16
4
2 3
3 4
4 5
5 6
36123
1
2374859 3029382
17
1
3 18132

Sample Output

2
13195
13

题意

给出A1~Ah,B1~Bh,M,H,求(A1B1+A2B2+ ... +AHBH)mod M.

做法

快速幂取模+累加步步取模

HIT

取模相当于在原数中不断减去M直到原数小于M,所以累加后取模和步步取模结果相同,因此在累加过程中取模以防止超过long long界限

CODE

#include <stdio.h>
long long z,h,a,b,m,ans,pow;


int main(){
scanf("%I64d",&z);

while(z--){
scanf("%I64d %I64d",&m,&h);

ans=0;
while(h--){
scanf("%I64d %I64d",&a,&b);

pow=1;
while(b>=1){
if(b%2==1)
pow=a*pow%m;
a=a*a%m;
b/=2;
}

ans+=pow;
ans%=m;
}

printf("%I64d\n",ans);
}

return 0;
}

分享到:
评论

相关推荐

    C语言快速幂取模算法小结

    本文实例汇总了C语言实现的快速幂取模算法,是比较常见的算法。分享给大家供大家参考之用。具体如下: 首先,所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求一个幂式的模(余)。在程序设计过程中,...

    C++快速幂取模.cpp

    C++快速幂取模代码,可根据需要自行调整优化,刷题的时候计算溢出可以用它解决,算法入门代码,可以直接复制使用

    快速幂取模 c/c++

    快速幂取模,一个运算技巧,用的着的话可以下载看下,自己做题常用它,

    快速幂取模.pptx

    这是一个关于学习快速幂取模的PPT,里面包含了关于快速幂取模的编码模板以及各类知识点,同时还可以到本人博客中查询关于快速幂取模的例题链接(寒假培训—快速幂取模)同时配有个人题解。

    蒙格马利快速幂取模 C语言实现

    蒙格马利快速幂取模,O(log(n))的快速算法,基于二进制扫描。

    快速幂取模,大数幂次求模,a^p%m

    本函数输入a,p,m,结果输出为a的p次方对m求模的结果。

    快速幂_取模 python实现

    函数原型 power_n__module_p(x,n,p): x: 幂底 n: 指数 p: 模数 调用示例: power_n__module_p(3,97,353) 输出: 40

    Java语言实现快速幂取模算法详解

    主要介绍了Java语言实现快速幂取模算法详解,具有一定参考价值,需要的朋友可以了解下。

    高次幂取模

    C++代码写的;主要是搞ACM题目关于高次幂快速取模的代码,希望对你们有帮助;

    MATLAB中,求模q下的快速幂,即(a^m)modq,函数qmi.m

    MATLAB中,求模q下的快速幂,即(a^m)modq,一个函数qmi.m,按要求传入参数调用就可以用,含参数使用注释。 MATLAB中,求模q下的快速幂,即(a^m)modq,一个函数,按要求传入参数调用就可以用。

    Rabin-Miller快速素数测试

    Rabin-Miller快速素数测试,使用蒙格马利快速幂取模实现,时间复杂度O(t*log(n))

    Gcd10928192.rar

    包括厄拉多塞筛法、欧几里得算法、快速幂取模、中国剩余定理、素性检测算法的实现的java和c的具体代码,是密码学实验的最基础的实验内容

    RSA加密及AES对称加密代码实现

    最近老师布置了两个加密的作业,记录一下编码过程及遇到的问题。 对于RSA解密基本内容这里就不赘述,直接说一下编码过程把: 1:N = p*q(p、q互质,即公...快速幂取模和辗转相除可自行百度 在加密和解密的时候一定要注

    acm模板(全)

    2.3 快速幂取模B^LmodP(O(logb)) 22 2.4 Fermat小定理 22 2.5 Rabin-Miller伪素数测试 22 2.6 Pollard-rho 22 2.7 扩展欧几里德算法extended-gcd 24 2.8 欧拉定理 24 2.9 线性同余方程ax≡b(mod n) 24 2.10 中国剩余...

    ACM模板(几乎全)

    2.3 快速幂取模B^LmodP(O(logb)) 22 2.4 Fermat小定理 22 2.5 Rabin-Miller伪素数测试 22 2.6 Pollard-rho 22 2.7 扩展欧几里德算法extended-gcd 24 2.8 欧拉定理 24 2.9 线性同余方程ax≡b(mod n) 24 2.10 中国剩余...

    C++快速幂与大数取模算法示例

    主要介绍了C++快速幂算法和大数取模算法的示例,对C++程序员来说有一定的帮助,有需要的朋友可以参考借鉴,下面来一起看看。

    矩阵快速幂_矩阵快速幂_

    c++ 矩阵快速幂封装支持矩阵乘法取模等

    RSA算法的纯Python实现

    这个库是计算乘模运算,幂模运算(蒙哥马利算法),最大公约数算法及扩展最大公约数算法(扩展欧几里得算法)等。 2、质数库。Miller_Rabin素数判断法,大整数快速因式分解算法(pollard_rho算法),生成指定位数的...

Global site tag (gtag.js) - Google Analytics