zoukankan      html  css  js  c++  java
  • 快速幂取模

    快速幂取模就是在O(logn)内求出an mod b的值。算法的原理是ab mod c=(a mod c)(b mod c)mod c


     设计一个基于二分的递归算法

    C++代码:

    long exp_mod(long a,long n,long b)
    {
        long 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;
    }

    证明:ab mod c=(a mod c)(b mod c)mod c

    假设

    a = Ac + B;

    b = Cc + D;

    所以

    a * b = ACc*c + ADc + BCc + BD;

    a * b % c = BD % c;

    a % c = B;

    b % c = D;

    (a % c)(b % c) % c = BD % c;

    所以

    ab % c = (a % c)(b % c) % c


    进阶版大数取模:

    LeetCode 372.Super Pow

    你的任务是计算ab mod 1337,a是一个正整数和b是一个非常大的正整数数组的形式给出。

    Example 1:

    Input: a = 2, b = [3]
    Output: 8
    

    Example 2:

    Input: a = 2, b = [1,0]
    Output: 1024

    思路:

    参考:C++ Clean and Short Solution

    一个知识点:ab mod c=(a mod c)(b mod c)mod c

    因为这里的幂是一个数组,我们最好依次来处理数组的位数。

    我们可以观察到:a1234567 % c = (a1234560 % c) * (a7 % c) % c = ((a123456)10) % c) * (a7 % c) % c

    看起来有点复杂,我们换一种方式:

    用f(a, b)来表示ab % c,然后使用 f 翻译上面的公式:

    f(a,1234567) = f(a, 1234560) * f(a, 7) % c = f(f(a, 123456),10) * f(a,7)%c;

     

    C++代码:

    class Solution {
    public:
        const int base = 1337;
        int superPow(int a, vector<int>& b) {
            if(b.empty()) return 1;
            int c = b.back();
            b.pop_back();
            return pow_mod(superPow(a, b), 10) * pow_mod(a, c) % base; 
        }
        
        int pow_mod(int a, int k)
        {
            a = a % base;
            int result = 1;
            for(int i = 0; i < k; i++)
                result = (result * a) % base;
            return result;
        }
    };

  • 相关阅读:
    字符串的全排列

    链表
    青蛙跳一格或者两格,n格跳法
    二叉树
    Concurrent实现原理
    sql语句总结 (转) http://blog.csdn.net/fengfeng91/article/details/15029173
    ArrayList实现原理
    java虚拟机 内存分配
    【转】关于Quartus ii无法识别Modelsim路径的问题
  • 原文地址:https://www.cnblogs.com/zkfopen/p/11321221.html
Copyright © 2011-2022 走看看