1.首先我们来看一个题:
求A^B的最后三位数表示的整数。
说明:A^B的含义是“A的B次方”
Input
输入数据包含多个测试实例,每个实例占一行,由两个正整数A和B组成(1<=A,B<=10000),如果A=0, B=0,则表示输入数据的结束,不做处理。
Output
对于每个测试实例,请输出A^B的最后三位表示的整数,每个输出占一行。
这是一个求幂运算的ACM试题,是一个很简单的东西。但是,前提是你要知道怎么处理。我们来看一下
2.这个题让你把数字求出来再取模显然是不可能的,因为没有这么大的数据类型(当然,我说的数c++)。所以我们可以使用快速幂的方法。快速幂的定义以及使用我就不说了,其实原理十分的简单,比如说让你求2^32,你会把它转换为4^16,继续转化16^8,继续下去是32^4.这样下去,本来需要计算32次,现在只需要4次,这就是快速幂的思想。是不是很简单。基于这个思路,我们来解决一下这个问题。
int PowerMod(long long a, long long b, int n)
{
int ans = 1;
a = a % n;
while (b>0)
{
if (b % 2 == 1)
ans = (ans*a) % n;
b /= 2;
a = (a*a) % n;
b = b >> 1;
};
return ans;
}
分析:计算a^b对n的模。首先对n取模,如果是b是奇数,那么当前值更新,如果是偶数,权重更新。就是这么easy.
下面看一下他的推广:很著名的斐波那契数列。其实满足一个矩阵是一个顺序的二阶矩阵。
#include <iostream>
using namespace std;
const int num = 2;
const int mod = 10000;
struct mat {
int m[num][num];
};
mat I{
1,0,
0,1
};
mat mul(mat a, mat b) {
mat ans;
for(int i=0;i<num;i++)
for (int j = 0; j < num; j++) {
ans.m[i][j] = 0;
for (int k = 0; k < num; k++)
ans.m[i][j] += (a.m[i][k] * b.m[k][j]);
ans.m[i][j] %= mod;
}
return ans;
}
mat quick_pow(mat a, long long b) {
mat ans = I;
mat tmp = a;
while (b > 0) {
if (b & 1)
ans = mul(ans, tmp);
tmp = mul(tmp, tmp);
b >>= 1;
}
return ans;
}
int main() {
long long n;
mat a{
1,1,
1,0
};
while (cin >> n&&n!=-1) {
mat tmp;
tmp = quick_pow(a, n);
cout << tmp.m[0][1] << endl;
}
return 0;
}
可以如上实现,tem是一个二阶矩阵,其中tem[0][0]是斐波那契数列的第N+1项,紧接着是第N项,然后第二行第一列是第n项,第二列是第n-1项。
以上就是矩阵快速幂的应用