快速幂和快速乘

快速幂

2^10 = 2^5 * 2^5;
2^5 = 2 * 2^4;
2^4 = 2^2 * 2^2;
2^2 = 2^1 * 2^1;
2^1 = 2 * 2^0;
有些时候偶数的情况就只需要乘它本身就够了,时间复杂度少了很多,这样的话2^10只需要5步就可以求出来了,但是循环的话,却需要十次。
在二进制中假如是2^10那么10对应的二进制就是1010,那么1号位,3号位都是1,所以就有了10 = 23+21=8+2,所以210=28+2^2。
所以二进制就先初始化ans = 1,用来存放累积的结果,然后判断b的二进制吗末尾是否为一来判断是奇数还是偶数,如果是奇数就乘以a,然后让a平方,并且b右移一位。只要b等于0,就返回ans。

时间复杂度为:log(n)

模板

ll poww(ll a, ll b, ll mod) {
    ll ans = 1;
    while(b > 0) {
        if(b & 1) {
            ans = ans * a % mod;
        }
        a = a * a % mod;
        b >>= 1;
    }
    return ans;
}
}

习题

a^b

快速乘

可以把 a * b这样算:
a * b = a + a + a + …+ a

a * 1 = a
a * 2 = 2a
a * 4 = 4a
a * 8 = 8a

所以可以推出:
a * (2 ^ k) = 2 ^ k * a

优点:不会爆范围

模板

ll ksc(ll a, ll b, ll mod) {
    ll ans = 0;
    while(b > 0) {
        if(b & 1) {
            ans = (ans + a) % mod;
        }
        a = (a + a) % mod;
        b >>= 1;
    }
    return ans;
}

习题

64位整数乘法

你可能感兴趣的:(模板,算法)