hdu3306 Another kind of Fibonacci

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2046    Accepted Submission(s): 813


Problem Description
As we all known , the Fibonacci series : F(0) = 1, F(1) = 1, F(N) = F(N - 1) + F(N - 2) (N >= 2).Now we define another kind of Fibonacci : A(0) = 1 , A(1) = 1 , A(N) = X * A(N - 1) + Y * A(N - 2) (N >= 2).And we want to Calculate S(N) , S(N) = A(0) 2 +A(1) 2+……+A(n) 2.

 

Input
There are several test cases.
Each test case will contain three integers , N, X , Y .
N : 2<= N <= 2 31 – 1
X : 2<= X <= 2 31– 1
Y : 2<= Y <= 2 31 – 1
 

Output
For each test case , output the answer of S(n).If the answer is too big , divide it by 10007 and give me the reminder.
 

Sample Input
   
   
   
   
2 1 1 3 2 3
 

Sample Output
   
   
   
   
6 196
 

Author
wyb
 


这题可以用矩阵快速幂做,构造【A[n-2],A[n-1],A[n-1]*A[n-1],A[n-1]*A[n-2],A[n-2]*A[n-2],S[n-1]】*A=【A[n-1],A[n],A[n]*A[n],A[n]*A[n-1],A[n-1]*A[n-1],S[n]】.

             0 y 0         0 0    0

             1 x 0         0 0    0 

其中A=0 0 x*x     x 1   x*x

             0 0 2*x*y y 0   2*x*y

             0 0 y*y     0 0   y*y

             0 0 0        0  0     1

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 99999999
#define pi acos(-1.0)
#define MOD 10007

struct matrix{
    ll n,m,i;
    ll data[8][8];
    void init_danwei(){
        for(i=0;i<n;i++){
            data[i][i]=1;
        }
    }
};

matrix multi(matrix &a,matrix &b){
    ll i,j,k;
    matrix temp;
    temp.n=a.n;
    temp.m=b.m;
    for(i=0;i<temp.n;i++){
        for(j=0;j<temp.m;j++){
            temp.data[i][j]=0;
        }
    }
    for(i=0;i<a.n;i++){
        for(k=0;k<a.m;k++){
            if(a.data[i][k]>0){
                for(j=0;j<b.m;j++){
                    temp.data[i][j]=(temp.data[i][j]+(a.data[i][k]*b.data[k][j])%MOD )%MOD;
                }
            }
        }
    }
    return temp;
}

matrix fast_mod(matrix &a,ll n){
    matrix ans;
    ans.n=a.n;
    ans.m=a.m;
    memset(ans.data,0,sizeof(ans.data));
    ans.init_danwei();
    while(n>0){
        if(n&1)ans=multi(ans,a);
        a=multi(a,a);
        n>>=1;
    }
    return ans;
}



int main()
{
    ll n,x,y,m,i,j;
    while(scanf("%lld%lld%lld",&n,&x,&y)!=EOF)
    {
        x=x%MOD;
        y=y%MOD;
        matrix a;
        a.n=a.m=6;
        memset(a.data,0,sizeof(a.data));
        a.data[0][1]=a.data[3][3]=y;
        a.data[1][1]=a.data[2][3]=x;
        a.data[2][4]=a.data[1][0]=a.data[5][5]=1;
        a.data[2][2]=a.data[2][5]=x*x%MOD;
        a.data[4][2]=a.data[4][5]=y*y%MOD;
        a.data[3][2]=a.data[3][5]=2*x*y%MOD;

        matrix ans;
        ans=fast_mod(a,n-1);

        matrix cnt;
        cnt.n=1;cnt.m=6;
        cnt.data[0][0]=cnt.data[0][3]=cnt.data[0][4]=1;
        cnt.data[0][1]=cnt.data[0][2]=1;
        cnt.data[0][5]=2;

        matrix ant;
        ant=multi(cnt,ans);

        printf("%lld\n",ant.data[0][5]);
    }
    return 0;
}


你可能感兴趣的:(矩阵快速幂)