1. 程式人生 > >HDU 5950 Recursive sequence

HDU 5950 Recursive sequence

T組資料, 每次給你 n A B 三個數字。

f[1] = A  , f[2] = B  ,  f[n] = 2 * f[n-2] + f[n-1] + n^4

思路: 啊啊啊啊啊 矩陣快速冪 一定先要去構造單位矩陣

式子1 : f[i] = 2 * f[i - 2] + f[i - 1] + i ^ 4

式子2 : f[i + 1] = 2 * f[i - 1] + f[i] + (i + 1) ^ 4

把(i + 1)^4 用二項式定理展開  (i + 1) ^ 4 = i ^ 4 + 4 * i ^ 3 + 6 * i ^ 2 + 4 * i + 1

然後把式子1寫成式子2的樣子

式子3 :  f[i] = 2 * f[i - 2] + f[i - 1] + i ^ 4 + 0 * i ^ 3 + 0 * i ^ 2 + 0 * i + 0 *1

也就是說 f[i+1] 只的(i+1)的4次方 可以通過 i^3, i^2, i^1, 1 構造出來。 

則 f[3] = 2 * f[1] + f[2] + 3^4   而3^4可以寫成 (2 + 1)^4  =  1 * 2^4 + 4* i^3 + 6 * i^2 + 4 * i + 1  

^ - ^ 然後xjb構造矩陣吧   

\begin{pmatrix} f2 & f1 & { 2 }^{ 4 } & { 2 }^{ 3 } & { 2 }^{ 2 } & { 2 }^{ 1 } & 1 \end{pmatrix}\begin{pmatrix} 1 & 1 & 0 & 0 & 0 & 0 & 0 \\ 2 & 0 & 0 & 0 & 0 & 0 & 0 \\ 1 & 0 & 1 & 0 & 0 & 0 & 0 \\ 4 & 0 & 4 & 1 & 0 & 0 & 0 \\ 6 & 0 & 6 & 3 & 1 & 0 & 0 \\ 4 & 0 & 4 & 3 & 2 & 1 & 0 \\ 1 & 0 & 1 & 1 & 1 & 1 & 1 \end{pmatrix}\quad =\quad \begin{pmatrix} f2+2f1+{ 3 }^{ 4 } & f2 & { 3 }^{ 4 } & { 3 }^{ 3 } & { 3 }^{ 2 } & { 3 }^{ 1 } & 1 \end{pmatrix}

上程式碼:

//
//  HDU5950 - Recursive sequence.cpp
//  數論
//
//  Created by Terry on 2018/9/29.
//  Copyright © 2018年 Terry. All rights reserved.
//

#include <stdio.h>
typedef long long LL;
long long read(){
    long long x = 0, f = 1;
    char ch=getchar();
    while(ch < '0' || ch > '9'){if(ch=='-') f = -1; ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
const int maxn = 7;
const long long mod = 2147493647;
struct Matrix{
    long long m[maxn][maxn];
}unit;
Matrix operator * (Matrix a, Matrix b){
    Matrix ret;
    LL x;
    int n = 7;
    for(int i = 0; i < n; ++i){
        for(int j = 0; j < n; ++j){
            x = 0;
            for(int k = 0; k < n; ++k){
                x += ((LL)a.m[i][k] * b.m[k][j]) % mod;
            }
            ret.m[i][j] = (x) % mod;
        }
    }
    return ret;
}
void init_unit(){
    // 單位矩陣
    for(int i = 0; i < maxn; ++i){
        unit.m[i][i] = 1;
    }
}
Matrix pow_mat(Matrix a, LL n){
    Matrix ans = unit;
    while (n) {
        if(n & 1){
            ans = ans * a;
        }
        a = a * a;
        n >>= 1;
    }
    return ans;
}
int main(){
    // 初始化單位矩陣
    init_unit();
    LL T = read();
    while (T--) {
        LL n = read();
        Matrix ans, a;
        LL A = read();
        LL B = read();
        if(n == 1){
            printf("%lld\n", A);
        }
        else if(n == 2){
            printf("%lld\n", B);
        }
        else{
            ans.m[0][0] = B; ans.m[0][1] = A; ans.m[0][2] = 16; ans.m[0][3] = 8; ans.m[0][4] = 4; ans.m[0][5] = 2; ans.m[0][6] = 1;
            
            a.m[0][0]=1; a.m[0][1]=1; a.m[0][2]=0; a.m[0][3]=0; a.m[0][4]=0; a.m[0][5]=0; a.m[0][6]=0;
            a.m[1][0]=2; a.m[1][1]=0; a.m[1][2]=0; a.m[1][3]=0; a.m[1][4]=0; a.m[1][5]=0; a.m[1][6]=0;
            a.m[2][0]=1; a.m[2][1]=0; a.m[2][2]=1; a.m[2][3]=0; a.m[2][4]=0; a.m[2][5]=0; a.m[2][6]=0;
            a.m[3][0]=4; a.m[3][1]=0; a.m[3][2]=4; a.m[3][3]=1; a.m[3][4]=0; a.m[3][5]=0; a.m[3][6]=0;
            a.m[4][0]=6; a.m[4][1]=0; a.m[4][2]=6; a.m[4][3]=3; a.m[4][4]=1; a.m[4][5]=0; a.m[4][6]=0;
            a.m[5][0]=4; a.m[5][1]=0; a.m[5][2]=4; a.m[5][3]=3; a.m[5][4]=2; a.m[5][5]=1; a.m[5][6]=0;
            a.m[6][0]=1; a.m[6][1]=0; a.m[6][2]=1; a.m[6][3]=1; a.m[6][4]=1; a.m[6][5]=1; a.m[6][6]=1;

            a = pow_mat(a, n - 2);
            ans = ans * a;

            printf("%lld\n", ans.m[0][0] % mod);
        }
    }
    return 0;
}