快速幂

ana^n可以把它拆成a×a×a×...×ana\underbrace{a \times a\times a \times ...\times a }_{n个a} 此算法的时间复杂度为O(n)O(n)

但它不够快!!!

考虑优化上面的算法

a2n=(an)2\because a^{2n}=(a^n)^2

\therefore可以把时间复杂度降到O(logn)O(logn)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//递归方法
long long binpow(long long a, long long b) {
if (b == 0) return 1;
long long res = binpow(a, b / 2);
if (b % 2)
return res * res * a;
else
return res * res;
}

//非递归方法
long long binpow(long long a, long long b) {
long long res = 1;
while (b > 0) {
if (b & 1) res = res * a;
a = a * a;
b >>= 1;
}
return res;
}

然后就会注意到一个问题,因为时间复杂度是O(logn)O(logn),所以nn最大可以取1e61e6

1e61e61e6^{1e6}似乎用高精都会TLE

所以我们可以在过程中取模,像下面这样:

1
2
3
4
5
6
7
8
9
10
11
//求a ^ b mod m 的值
long long binpow(long long a, long long b, long long m) {
a %= m;
long long res = 1;
while (b > 0) {
if (b & 1) res = res * a % m;
a = a * a % m;
b >>= 1;
}
return res;
}