首页  编辑  

快速模幂算法

Tags: /超级猛料/Alogrith.算法和数据结构/常用算法的C代码/   Date Created:
如果要求 a^b%c,例如今天是星期六,10^100天后是星期几??

解答:
10^100=(3+7)^100 
3^100=9^50=(2+7)^50

2^50=32^10=(28+4)^10 
4^10=16^5=(14+2)^5 
2^5/7=4…….4 
再过4天是星期三

直接计算a的b次方,数据可能非常大,所以必须用上面的模幂方法来实现。
模幂的算法,是每次把底数对模数取余,因为整除的无论是多少次方,都是回到原点的,例如 7无论多少次方,除以7永远都是余数为0!
取余之后,对剩下的余数再进行幂运算,计算即可。
因为取余之后,余数就小于底数了,所以我们要把余数*余数,同时把指数/2,这样才是等价变换。

按上面的方式,不断循环处理就可以了,直到指数为0,停止循环。
当然,如果指数是偶数,那么刚好可以除以2,如果指数是奇数,那么我们要把多出来的一个底数与余数相乘,才能继续多项式变化。例如:
5^7次方,是等价于 5 * 5^6的

上面的过程可以理解为:
#include <iostream>
#include <string>
using namespace std;

const int DAYS = 7;
string days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

// 快速模幂函数
int powermod(int a, int n, int m)
{
   int res = 1L;
    while(n) {
        if(n & 1L) {  // 如果指数是奇数,需要把多出来的与底数a相乘
            res *= a;
            res %= m;
        }

        a *= a;
        a %= m;
        n >>= 1; // 指数 整除 2
    }

    return res;
}

int main()
{
    int a, b, start = 0;
    cin >> a >> b;
    cout << days[(start + powermod(a, b, DAYS)) % DAYS] << endl;
     return 0;
}