思路:
用矩阵快速幂优化dp
代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL unsigned long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int MOD = 1e9 + 7; const int M = 1<<5; int m; LL n; struct Matrix { LL a[M][M]; void init() { for (int i = 0; i < (1<<m); i++) { for (int j = 0; j < (1<<m); j++) a[i][j] = 0; } } void _init() { init(); for (int i = 0; i < (1<<m); i++) { a[i][i] = 1; } } }A; Matrix mul(Matrix A, Matrix B) { Matrix ans; ans.init(); for (int i = 0; i < (1<<m); i++) { for (int j = 0; j < (1<<m); j++) { if(A.a[i][j]) { for (int k = 0; k < (1<<m); k++) ans.a[i][k] = (ans.a[i][k] + A.a[i][j] * B.a[j][k]) % MOD; } } } return ans; } Matrix q_pow(Matrix A, LL k) { Matrix ans; ans._init(); while(k) { if(k&1) ans = mul(ans, A); A = mul(A, A); k >>= 1; } return ans; } int main() { scanf("%d %lld", &m, &n); for (int i = 0; i < (1<<m); i++) { for (int j = 0; j < (1<<m); j++) { bool f = true; for (int k = 0; k < m; k++) { if(!(i&(1<<k)) && !(j&(1<<k))) { f = false; break; } } if(i == (1<<m)-1 && j == i) f = false; A.a[i][j] = f; } } A = q_pow(A, n-1); LL ans = 0; for (int i = 0; i < (1<<m); i++) { for (int j = 0; j < (1<<m); j++) { ans = (ans + A.a[i][j]) % MOD; } } printf("%lld ", ans); return 0; }