D - Another kind of Fibonacci

HDU - 3306

直接根据题意构造矩阵

\[ \left[ \begin{array}{ccc} A_{n-2}\\\\ A_{n-1}\\\\ A_{n-2}*A_{n-1}\\\\ A_{n-2}^2\\\\ A_{n-1}^2\\\\ S_{n-1}\\\\ \end{array} \right] * \left[ \begin{array}{ccc} 0 & 1 & 0 & 0 & 0 & 0 \\\\ y & x & 0 & 0 & 0 & 0 \\\\ 0 & 0 & y & 0 & x & 0 \\\\ 0 & 0 & 0 & 0 & 1 & 0 \\\\ 0 & 0 & 2*x*y & y * y & x * x & 0 \\\\ 0 & 0 & 2*x*y & y * y & x * x & 1 \\\\ \end{array} \right] = \left[ \begin{array}{ccc} A_{n-1}\\\\ A_{n}\\\\ A_{n-1}*A_{n}\\\\ A_{n-1}^2\\\\ A_{n}^2\\\\ S_{n}\\\\ \end{array} \right] \]


#include<bits/stdc++.h>
using namespace std;

const int mod = 10007;

struct jz{
    long long g[10][10];
    void init(){
        memset(g,0,sizeof(g));
    }
    void one(){
        memset(g,0,sizeof(g));
        for(int i = 1; i <= 6; ++ i) g[i][i] = 1;
    }
};
jz operator * (jz a,jz b){
    jz c; c.init();
    for(int i = 1; i <= 6; ++ i)
    for(int j = 1; j <= 6; ++ j)
    for(int k = 1; k <= 6; ++ k)
    c.g[i][j] += a.g[i][k] * b.g[k][j] % mod, c.g[i][j] %= mod;
    return c;
}
jz ksm(jz x,long long y){
    jz z; z.one();
    while(y){
        if(y & 1) z = z * x;
        y >>= 1;
        x = x * x;
       
    }
    return z;
}

jz a,b;
long long n,x,y;

int main(){
    while(scanf("%lld%lld%lld",&n,&x,&y) != EOF){
        a.init(); b.init(); x %= mod; y %= mod; 
        a.g[1][2] = 1;
        a.g[2][1] = y; a.g[2][2] = x;
        a.g[3][3] = y; a.g[3][5] = x;
        a.g[4][5] = 1;
        a.g[5][3] = 2 * x * y % mod; a.g[5][4] = y * y % mod; a.g[5][5] = x * x % mod;
        a.g[6][3] = 2 * x * y % mod; a.g[6][4] = y * y % mod; a.g[6][5] = x * x % mod; a.g[6][6] = 1;
        
        /*b.g[1][1] = 1;
        b.g[2][1] = 1;
        b.g[3][1] = 1;
        b.g[4][1] = 1;
        b.g[5][1] = 1;
        b.g[6][1] = 2;*/
        
        n -= 1;
        a = ksm(a, n);
        
        long long ans = 0;
        ans += (a.g[6][3] + a.g[6][4]) % mod, ans %= mod;
        //printf("%lld\n",ans);
        ans += (a.g[6][5] + 2 * a.g[6][6] % mod) % mod, ans %= mod;
        printf("%lld\n",ans);
        
        /*for(int i = 1; i <= 6; ++ i){
            printf("%lld ",a.g[6][i]);
            puts("");
        }
        
        b = b * a;
        
        printf("%lld\n",b.g[6][1]);*/
    }
    return 0;
}



/*

An-2          010000         An-1
An-1          yx0000         An
An-2 * An-1   00y0x0         An-1*An
An-2^2        000010         An-1^2
An-1^2        002xyYX0         An^2   
S(n-1)        002xyYX1                S(n)    

*/

posted @ 2020-07-21 16:12  zhuzihan  阅读(76)  评论(0编辑  收藏  举报