zoukankan      html  css  js  c++  java
  • 快速幂算法

    在计算形如ab的运算时,如果用朴素的算法需要O(b)的时间复杂度,当b很大时显然是不可取的,于是我们希望找到一种快速的算法来计算,尤其是题目中要求答案取模时。

    对于朴素的算法我们有

    ans=1;

    for(int i=1;i<=b;i++) (ans*=a)%=mod;

    我们可以简单优化一下,在循环之前加入a%=mod;

     

    当b为偶数时我们可以这样

    int ans=1;

    a%=mod;

    (a*=a)%=mod;

    for(int i=1;i<=b/2;i++)

    {

    (ans*=a)%=mod;

    }

    当b为奇数时需要特判

    int ans=1;

    a%=mod;

    if(b&1) ans*=a;

    (a*=a)%=mod;

    for(int i=1;i<=b/2;i++)

    {

    (ans*=a)%=mod;

    }

    这样做可以将时间减半。

     

    我们甚至可以这样

    int ans=1;

    a%=mod;

    if(b&1) ans*=a;

    (a*=a)%=mod;

    b/=2;

    if(b&1) (ans*=a)%=mod;

    (a*=a)%=mod;

    b/=2;

    for(int i=1;i<=b;i++) (ans*=a)%=mod;

     

    那么我们自然会想到,如果时间可以减半,减半,再减半,那么时间复杂度可以降到O(log n).

    实现方法也很简单,就是把上述步骤迭代多次。

    代码如下:

     

    int ans=1;
    a%=mod;
    while(b)
    {
        if(b&1) (ans*=a)%=mod;
        b/=2;//可以知道任何一个大于1的数经历多次这步均可以达到b=1,所以不用担心ans最后得不到a的值
        (a*=a)%=mod;
    } 
    View Code

    典型例题:NOIP201305转圈游戏

  • 相关阅读:
    简单的多重背包
    完美子图
    活动投票
    人品问题
    售票系统
    最短路径
    优美值
    前端-常用函数记录-持续更新
    前端-单点登录中cookie中domain的思考
    大白话说GIT常用操作,常用指令git操作大全
  • 原文地址:https://www.cnblogs.com/16er/p/5157374.html
Copyright © 2011-2022 走看看