版权声明:那个,最起码帮我加点人气吧,署个名总行吧 https://blog.csdn.net/qq_41670466/article/details/82817722
今天在补acmicpc焦作网络预选赛题,补L题时发现看不懂代码,后来学长告诉我这个代码用的是矩阵快速幂,还有一种算法是杜教BM自动机,这个以后再说,于是自己便找了个矩阵快速幂的模板题学习一下。
矩阵快速幂的作用是简化递推的过程,比如斐波那契数列就可以用矩阵快速幂来表示通过矩阵乘法可以得到f(n)=f(n-1)+f(n-2) 图中矩阵乘法可以看成T*a(n-1)=a(n) 其中T为常数矩阵,向下回溯可以得到A(n)=T^n-1*a1其中a1为初始矩阵也就是当n=1时的值,那么答案就是res[1][1](res是等号后面的矩阵)具体的可以参见大佬写的矩阵快速幂总结很详细
在这道题中就用到上图的表示;
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 2;
const int mod = 1e+4;
struct Matrix
{
int mat[maxn][maxn];
Matrix(){}
Matrix operator *(Matrix const &b)const
{
Matrix res;
memset(res.mat, 0, sizeof(res.mat));
for (int i = 0; i < maxn; i++)
for (int j = 0; j < maxn; j++)
for (int k = 0; k < maxn; k++)
res.mat[i][j] = (res.mat[i][j] + this->mat[i][k] * b.mat[k][j]) % mod;
return res;
}
};
Matrix Quickpow(Matrix base, int n)
{
Matrix res;
memset(res.mat, 0, sizeof(res.mat));
for (int i = 0; i < maxn; i++)
res.mat[i][i] = 1;
while (n>0)
{
if (n & 1)
res = res * base;
base = base * base;
n >>= 1;
}
return res;
}
int main()
{
Matrix base;
for (int i = 0; i < maxn; i++)
for (int j = 0; j < maxn; j++)
base.mat[i][j] = 1;
base.mat[1][1] = 0;
int n;
while (~scanf("%d", &n) && n != -1)
{
if (n != 0)
{
Matrix ans = Quickpow(base, n - 1);
printf("%d\n", ans.mat[0][0]);
}
else
printf("0\n");
}
system("pause");
return 0;
}