Reprinted from: http://www.cnblogs.com/CXCXCXC/p/4641812.html
Reference: https://baike.baidu.com/item/quick power/5500243?fr=aladdin
The fast power is easy to understand, but it is easy to implement. I remember it a few times and always forget it. Today, I will summarize it systematically to prevent forgetting.
First of all, the purpose of fast exponentiation is to achieve fast exponentiation. Suppose we require a^b. According to the naive algorithm, a is multiplied by b times, so that the time complexity is O(b), which is O(n) level. , the fast power can do O(logn), which is much faster. Its principle is as follows:
Suppose we ask for a^b, then b can actually be split into binary, and the weight of the i-th bit of the binary number is 2^(i-1), for example, when b==11
int poww(int a, int b) { int ans = 1, base = a; while (b != 0) { if (b & 1 != 0) ans *= base; base *= base; b >>= 1; } return ans; }
The code is very short, and memorization is also feasible, but it is better to understand it. In fact, it is also very easy to understand. Take b==11 as an example, b=>1011, the binary is counted from right to left, but the order of multiplication is a^ (2^0)*a^(2^1)*a^(2^3), from left to right. We keep making base*=base the purpose of multiplying, so as to contribute to ans at any time.
It is necessary to understand the step of base*=base: because base*base==base 2 , the next multiplication is base 2 *base 2 ==base 4 , and then similarly base 4 *base 4 =base 8 , so you can Do base-->base 2 -->base 4 -->base 8 -->base 16 -->base 32 ....... The index is exactly 2^i, and look at the above example, a¹¹= a 1 *a 2 *a 8 , these three terms can be solved perfectly, and fast power is like this.
By the way, since the exponential function is a function of explosive growth, it is very likely that the range of int will explode. It is up to you to choose long long or mod a certain number according to the meaning of the question.
The same is true for the fast exponentiation of the matrix. Below is a matrix fast exponentiation template for finding the Fibonacci sequence.
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int mod = 10000; const int maxn = 35; int N; struct Matrix { int mat[maxn][maxn]; int x, y; Matrix() { memset(mat, 0, sizeof(mat)); for (int i = 1; i <= maxn - 5; i++) mat[i][i] = 1; } }; inline void mat_mul(Matrix a, Matrix b, Matrix &c) { memset(c.mat, 0, sizeof(c.mat)); c.x = a.x; c.y = b.y; for (int i = 1; i <= c.x; i++) { for (int j = 1; j <= c.y; j++) { for (int k = 1; k <= a.y; k++) { c.mat[i][j] += (a.mat[i][k] * b.mat[k][j]) % mod; c.mat[i][j] %= mod; } } } return ; } inline void mat_pow(Matrix &a, int z) { Matrix ans, base = a; ans.x = a.x; ans.y = a.y; while (z) { if (z & 1 == 1) mat_mul(ans, base, ans); mat_mul(base, base, base); z >>= 1; } a = ans; } int main() { while (cin >> N) { switch (N) { case -1: return 0; case 0: cout << "0" << endl; continue; case 1: cout << "1" << endl; continue; case 2: cout << "1" << endl; continue; } Matrix A, B; A.x = 2; A.y = 2; A.mat[1][1] = 1; A.mat[1][2] = 1; A.mat[2][1] = 1; A.mat[2][2] = 0; B.x = 2; B.y = 1; B.mat[1][1] = 1; B.mat[2][1] = 1; mat_pow(A, N - 1); mat_mul(A, B, B); cout << B.mat[1][1] << endl; } return 0; }