矩阵加速
题解:g( i + 1) = g(i) + g( i - 1) + i ^ 2,g(i) = g(i - 1) + g( i - 2) + ( i - 1 ) ^ 2;
#include<bits/stdc++.h> #define ll long long #define P pair<int,int> #define pb push_back #define lson root << 1 #define INF (int)2e9 + 7 #define maxn (int)1e6 + 7 #define rson root << 1 | 1 #define LINF (unsigned long long int)1e18 #define mem(arry, in) memset(arry, in, sizeof(arry)) using namespace std; const ll mod = 1000000007; struct node{ ll A[5][5]; node() { mem(A, 0); } node operator * (const node tp) { node ans; for(int i = 0; i < 5; i++){ for(int j = 0; j < 5; j++){ for(int k = 0; k < 5; k++){ ans.A[i][j] += A[i][k] * tp.A[k][j]; ans.A[i][j] %= mod; } } } return ans; } void operator = (const node tp) { for(int i = 0; i < 5; i++){ for(int j = 0; j < 5; j++){ A[i][j] = tp.A[i][j]; } } } }; node Fastpow(node C, ll x){ node B; for(int i = 0; i < 5; i++) B.A[i][i] = 1; while(x){ if(x & 1) B = B * C; C = C * C; x >>= 1; } return B; } int temp[5][5] = { {1, 1, 1, 0, 0}, {1, 0, 0, 0, 0}, {0, 0, 1, 2, -1}, {0, 0, 0, 1, 1}, {0, 0, 0, 0, 1} }; int main() { int T; cin >> T; while(T--){ int x; cin >> x; if(x == 1) cout << 1 << endl; else if(x == 2) cout << 2 << endl; else{ node y; for(int i = 0; i < 5; i++){ for(int j = 0; j < 5; j++) y.A[i][j] = temp[i][j]; } y = Fastpow(y, x - 2); printf("%lld\n", (2 * y.A[0][0] + y.A[0][1] + 4 * y.A[0][2] + 3 * y.A[0][3] + y.A[0][4]) % mod); } } return 0; }
题解:a(n) = 2a(n - 1) + 3a(n - 2) + n * 4^n + 5n^2 - 6,a(n + 1) = 2a(n) + 3a(n - 1) + (n + 1) * 4^(n + 1) + 5(n + 1)^2 - 6;
#include<bits/stdc++.h> #define ll long long #define P pair<int,int> #define pb push_back #define lson root << 1 #define INF (int)2e9 + 7 #define maxn (int)1e6 + 7 #define rson root << 1 | 1 #define LINF (unsigned long long int)1e18 #define mem(arry, in) memset(arry, in, sizeof(arry)) using namespace std; const ll mod = 998244353; struct node{ ll A[7][7]; node() { mem(A, 0); } node operator * (const node tp) { node ans; for(int i = 0; i < 7; i++){ for(int j = 0; j < 7; j++){ for(int k = 0; k < 7; k++){ ans.A[i][j] += A[i][k] * tp.A[k][j]; ans.A[i][j] %= mod; } } } return ans; } void operator = (const node tp){ for(int i = 0; i < 7; i++){ for(int j = 0; j < 7; j++) A[i][j] = tp.A[i][j]; } } }; node Fastpow(node C, ll x){ node B; for(int i = 0; i < 7; i++) B.A[i][i] = 1; while(x){ if(x & 1) B = B * C; C = C * C; x >>= 1; } return B; } int temp[7][7] = { {2, 3, 1, 0, 5, 0, mod-6}, {1, 0, 0, 0, 0, 0, 0}, {0, 0, 4, 4, 0, 0, 0}, {0, 0, 0, 4, 0, 0, 0}, {0, 0, 0, 0, 1, 2, 1}, {0, 0, 0, 0, 0, 1, 1}, {0, 0, 0, 0, 0, 0, 1} }; int main() { int T; cin >> T; while(T--){ int x; cin >> x; if(x == 0) cout << 0 << endl; else if(x == 1) cout << 1 << endl; else if(x == 2) cout << 48 << endl; else{ node y; for(int i = 0; i < 7; i++){ for(int j = 0; j < 7; j++) y.A[i][j] = temp[i][j]; } y = Fastpow(y, x - 1); printf("%lld\n", (y.A[0][0] + 32 * y.A[0][2] + 16 * y.A[0][3] + 4 * y.A[0][4] + 2 * y.A[0][5] + y.A[0][6]) % mod); } } return 0; }
经验:写成n+1的形式,然后展开,不同形式的就添加到列向量里面!!!!!