您的位置:首页 > 其它

hdu 3306 Another kind of Fibonacci(矩阵连乘)

2015-07-03 14:19 357 查看
题意:http://acm.hdu.edu.cn/showproblem.php?pid=3306

大意是这样的:f[0]=f[1]=1,f
=X*f[n-1]+Y*f[n-2].S
=f[0]^2+f[2]^2+--+f
^2.给定n,求出s
%10007。

要求出s
肯定不是逐个求出f[i]再平方相加求和。s
=s[n-1]+f
^2,f
^2=X^2*f[n-1]^2+Y^2*f[n-2]^2+2*X*Y*f[n-1]*f[n-2]。f
*f[n-1]=X*f[n-1]^2+Y*f[n-2]*f[n-1], s[1]=f[0]+f[1]=2。据此得到:




进一步还能推出:



有了它之后问题基本解决了。还有一点,输入的x,y要及时的Mod。

#include <iostream>
#include<cstdio>
using namespace std;
typedef long long LL;
const int mod=10007;
struct matrix{
    LL m[4][4];
};
matrix A;
/*1	x^2	y^2	2*x*y
0	x^2	y^2	2*x*y
0	1	0	0
0	x	0	y*/
matrix I={
    1,0,0,0,
    0,1,0,0,
    0,0,1,0,
    0,0,0,1
};
matrix multi(matrix a,matrix b){
    matrix c={0};
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++){
            for(int k=0;k<4;k++){
                c.m[i][j]+=a.m[i][k]*b.m[k][j]%mod;
            }
            c.m[i][j]%=mod;
        }
    }
    return c;
}
matrix power(matrix a,int k){
    matrix c=I;
    while(k){
        if(k&1){
            c=multi(c,a);
            k--;
        }
        k>>=1;
        a=multi(a,a);
    }
    return c;
}
void initalA(LL x,LL y){
   A={
            1,(x%mod)*(x%mod),(y%mod)*(y%mod),2*(x%mod)*(y%mod),
            0,(x%mod)*(x%mod),(y%mod)*(y%mod),2*(x%mod)*(y%mod),
            0,              1,              0,                0,
            0,          x%mod,              0,            y%mod
     };
   for(int i=0;i<4;i++){
       for(int j=0;j<4;j++){
           A.m[i][j]%=mod;
       }
   }
}
int main()
{
    LL n,x,y;
    while(cin>>n>>x>>y){
        initalA(x,y);
        matrix q=power(A,n-1);
        LL ans=q.m[0][0]*2+q.m[0][1]+q.m[0][2]+q.m[0][3];
        printf("%lld\n",ans%mod);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: