HDU 5950 Recursive sequence
阿新 • • 發佈:2018-12-12
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構造矩陣吧
上程式碼:
// // 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; }