将指数转化为用2进制表示的数
实数快速幂
LL qmi(int a, int b, int p)
{
LL res = 1;
while (b)
{
if (b & 1) res = res * a % p; // 如果幂次的二进制表示的这一位上是1
a = (LL) a * a % p; // 注意可能爆int范围
b >>= 1;
}
return res;
}
矩阵快速幂
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 110, mod = 1e9 + 7;
struct Matrix
{
int n;
int v[N][N];
Matrix operator * (const Matrix &b) const // 重载一下乘法运算符
{
Matrix c;
memset(c.v, 0, sizeof c.v); // 记得一定一定一定要清空
c.n = n;
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= n; j ++)
for (int k = 1; k <= n; k ++)
c.v[i][j] = ((LL) v[i][k] * b.v[k][j] % mod + c.v[i][j]) % mod;
return c;
}
}a, res;
int n;
LL k;
int main()
{
scanf ("%d %lld", &n, &k);
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= n; j ++)
{
scanf ("%d", &a.v[i][j]);
if (i == j) res.v[i][i] = 1; // 初始化res为单位矩阵
}
a.n = res.n = n;
while (k)
{
if (k & 1) res = a * res;
a = a * a;
k >>= 1;
}
for (int i = 1; i <= n; i ++)
{
for (int j = 1; j <= n; j ++)
printf ("%d ", res.v[i][j]);
puts("");
}
return 0;
}
构造一个基本矩阵,然后将求斐波那契数列时的递推加法变成矩阵快速幂加速
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
struct Fib
{
int v[3][3];
Fib operator * (const Fib &b) const
{
Fib c;
memset(c.v, 0, sizeof c.v);
for (int i = 1; i <= 2; i ++)
for (int j = 1; j <= 2; j ++)
for (int k = 1; k <= 2; k ++)
c.v[i][j] = ((LL) v[i][k] * b.v[k][j] % mod + c.v[i][j]) % mod;
return c;
}
}a, res;
LL n;
void qmi(LL k)
{
while (k)
{
if (k & 1) res = res * a;
a = a * a;
k >>= 1;
}
}
int main()
{
scanf ("%lld", &n);
if (n <= 2)
{
printf ("1");
return 0;
}
a.v[1][1] = a.v[1][2] = a.v[2][1] = 1;
res.v[1][1] = res.v[1][2] = 1;
qmi(n - 2);
printf ("%lld", res.v[1][1]);
return 0;
}