您的位置:首页 > 其它

hdu 1005 矩阵快速幂模板题

2016-02-10 19:28 423 查看
题意:A number sequence is defined as follows:

f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.

Given A, B, and n, you are to calculate the value of f(n).

分析:通常这类题,会给出一个公式,但是由于数据很大,时间复杂度很高,所以可以借助快速幂将a*b%k的复杂度降到logb,所以矩阵幂乘的复杂度可以降到O(n^3*logn).

主要是需要求出有效运算的矩阵,也就是幂乘的矩阵的形式。

此题的化简过程:

f(n)=A*f(n-1)+B*f(n-2) (Mathtype中,按住Shift和Ctrl,再按空格键,即可添加空格)

用矩阵乘法递推求得


递推可得

,这样只需求


对于

,当n为偶数时,


n为奇数时,


(以上过程copy自点击打开链接
有了幂乘的矩阵,就直接套模板求就行了。

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;
typedef long long ll;
const int mod=7;
const int N = 3;

struct Mat {
int mat

;
};
int n=2, m;
int A,B;

Mat operator * (Mat a, Mat b) {
Mat c;
memset(c.mat, 0, sizeof(c.mat));
int i, j, k;
for(k = 0; k < n; ++k) {
for(i = 0; i < n; ++i) {
for(j = 0; j < n; ++j) {
c.mat[i][j] += a.mat[i][k] * b.mat[k][j];
c.mat[i][j]%=mod;
}
}
}
return c;
}

Mat operator ^ (Mat a, int k) {
Mat c;
int i, j;
for(i = 0; i < n; ++i)
for(j = 0; j < n; ++j)
c.mat[i][j] = (i == j);

for(; k; k >>= 1) {
if(k&1) c = c*a;
a = a*a;
}
return c;
}

int main()
{
int i;
int k;
while(~scanf("%d%d%d",&A,&B,&k)&&(A+B+k)){
if(k==1||k==2)
{
printf("1\n");
continue;
}
Mat a;
a.mat[0][0]=A%mod;a.mat[0][1]=B%mod;
a.mat[1][0]=1;a.mat[1][1]=0;
Mat c=a^(k-2);
printf("%d\n",(c.mat[0][0]*1+c.mat[0][1]*1)%mod);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: