快速幂取模(2015.7.29)

取余数有%,即

10%3

可以得到1

但是当数比较大时(比如2999999),计算机可能就无法计算

然而,根据数论的结论,我们可以简化一下。

根据a*b mod c = ( (a mod c) * (b mod c) ) mod c

可以得出 an mod b = (a mod b)n mod b

所以,有 an mod b = (a mod b)n mod b = (a mod b)n/22 mod b = (an/2 mod b)2 mod b = (an/2 mod b)2 mod b

如果用exp_mod(a,n,b)表示an mod b那么就是exp_mod(a,n,b) = exp_mod(a,n/2,b)*exp_mod(a,n/2,b) mod b

那么我们可以不断二分幂,从而减小运算

有几种特殊情况需要考虑

  1. n=0,也即a^n=1,此时模为1%b
  2. n=1,这时二分已经到了终点,可以直接用a%b得到答案
  3. n为奇数,此时n/2会被舍去小数部分,会少乘一个a mod b,可以在补上a mod b

伪代码如下

exp_mod(a,n,b){//a^n mod b
    如果n=0
        返回 1 mod b
    如果n=1
        返回 a mod b
    temp=exp_mod(a,n/2,b)//往下二分
    temp=temp^2%b
    如果n是奇数
        temp=temp*a%b
    返回 temp
}

代码如下

typedef long long LL;
LL exp_mod(LL a,LL n,LL b){
    LL t;
    if(n==0) return 1%b;
    if(n==1) return a%b;
    t=exp_mod(a,n/2,b);
    t=t*t%b;
    if((n&1)==1) t=t*a%b;
    return t;
}

附上一道题 COGS-1130. 取余运算

时间: 2024-10-06 04:23:53

快速幂取模(2015.7.29)的相关文章

快速幂取模(POJ 1995)

http://poj.org/problem?id=1995 以这道题来分析一下快速幂取模 a^b%c(这就是著名的RSA公钥的加密方法),当a,b很大时,直接求解这个问题不太可能 利用公式a*b%c=((a%c)*b)%c 每一步都进行这种处理,这就解决了a^b可能太大存不下的问题,但这个算法的时间复杂度依然没有得到优化 由此可以用快速幂算法优化: http://www.cnblogs.com/qlky/p/5020402.html 再结合取模公式: (a + b) % p = (a % p

HDU 5363 Key Set【快速幂取模】

Key Set Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1886    Accepted Submission(s): 990 Problem Description soda has a set S with n integers {1,2,-,n}. A set is called key set if the sum

HDU 4965 Fast Matrix Calculation (矩阵快速幂取模----矩阵相乘满足结合律)

http://acm.hdu.edu.cn/showproblem.php?pid=4965 利用相乘的可结合性先算B*A,得到6*6的矩阵,利用矩阵快速幂取模即可水过. 1 #include<iostream> 2 #include<stdio.h> 3 #include<iostream> 4 #include<stdio.h> 5 #define N 1010 6 #define M 1010 7 #define K 6 8 using namespa

UVa 11582 (快速幂取模) Colossal Fibonacci Numbers!

题意: 斐波那契数列f(0) = 0, f(1) = 1, f(n+2) = f(n+1) + f(n) (n ≥ 0) 输入a.b.n,求f(ab)%n 分析: 构造一个新数列F(i) = f(i) % n,则所求为F(ab) 如果新数列中相邻两项重复出现的话,则根据递推关系这个数列是循环的. 相邻两项所有可能组合最多就n2中,所以根据抽屉原理得到这个数列一定是循环的. 求出数列的周期,然后快速幂取模即可. 1 #include <cstdio> 2 #include <iostrea

The 2018 ACM-ICPC China JiangSu Provincial Programming Contest快速幂取模及求逆元

题目来源 The 2018 ACM-ICPC China JiangSu Provincial Programming Contest 35.4% 1000ms 65536K Persona5 Persona5 is a famous video game. In the game, you are going to build relationship with your friends. You have N friends and each friends have his upper b

快速幂及快速幂取模

快速幂顾名思义,就是快速算某个数的多少次幂.其时间复杂度为 O(log?N), 与朴素的O(N)相比效率有了极大的提高.——bybaidu 快速幂可以用位运算这个强大的工具实现. 代码: 1 int pow(int a,int b) 2 { 3 int ans=1; 4 while(b!=0) 5 { 6 if(b&1) 7 ans*=a; 8 a*=a; 9 b>>=1; 10 } 11 return ans; 12 } 快速幂取模需要记住一个定理:积的取模等于取模积的取模:算法是蒙

关于快速幂取模

今天看算法书的时候,看到一道关于快速幂取模的题,心想好像不难,便写了一下,发现我的渣渣代码写的比正常的O(N)复杂度还要慢(天知道我怎么做到的T_T),渣渣代码如下: 1 public static long fastMi(long x,long n){ 2 if(n==1){ 3 return x; 4 } 5 if(n%2==0){ 6 return fastMi(x,n/2)*fastMi(x,n/2); 7 }else{ 8 return fastMi(x,n/2)*fastMi(x,n

快速幂取模算法

什么是快速幂? 快速幂应当是快速幂取模的简称 对于一般的求幂算法,求$a^b\,\bmod\,m$,即使用循环b次的方法,复杂度是$O(b)$的,当b很大的时候,这种算法就会显得十分缓慢. 快速幂是基于以下明显的事实: $${a^b} \equiv {(a^2)^{\frac{b}{2}}} \pmod{m}\quad b\ is\ even$$ $${a^b} \equiv {(a^2)^{\frac{b}{2}}*a} \pmod{m}\quad b\ is\ odd$$ 那么我们得到这样一

快速幂取模

参考文章来源:Reait  Home(http://www.reait.com/blog.html) 转载请注明,谢谢合作. 在Miller Rabbin测试素数,就用到了快速幂取模的思想.这里总结下.求a^b%c(这就是著名的RSA公钥的加密方法),当a,b很大时,直接求解这个问题不太可能 算法1:利用公式a*b%c=((a%c)*b)%c,这样每一步都进行这种处理,这就解决了a^b可能太大存不下的问题,但这个算法的时间复杂度依然没有得到优化 代码如下: 01.int modexp_simpl