Description [title]
Small \ (L \) has an annular garden, clockwise gardens, flower beds he respective numbered \ (. 1 \) ~ \ (N (2 <= N <= 10 ^ 15) \) . His ring-shaped garden will change a new pattern every day, but he's gardens are nothing more than a rule, any adjacent \ (M (2 \ le M \ le 5, M \ le N) \) a flowerbed no more than \ (K (1 \ le K <M) \) a \ (C \) shaped garden, flower garden rest are \ (P \) shaped flower bed.
The number of valid request scheme, the number of bad mold \ (1e9 + 7 \) modulo.
【analysis】
See \ (M \) is so small, it is easy to take into account the state press.
But seeing \ (N \) is so big, that fast power bar, complete this question.
【Code】
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define ll long long
#define debug() puts("FBI WARNING!")
using namespace std;
const int P = 19260817;
const int MOD = 1000000007;
const int MAX = 300000 + 5;
const int M = 5;
inline ll read(){
ll f = 1, x = 0; char ch;
do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0' || ch > '9');
do {x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
return f * x;
}
struct TOOL {
#define Hanabi ll
inline Hanabi max(Hanabi a, Hanabi b) { return a < b ? b : a; }
inline Hanabi min(Hanabi a, Hanabi b) { return a < b ? a : b; }
inline Hanabi abs(Hanabi a) { return a < 0 ? a : a; }
}t;
int m, K, jd[1 << M], limit, cover;
ll n, f[1 << M], vis[1 << M][1 << M], ans;
inline void mul() {
ll c[1 << M];
memset(c, 0, sizeof c);
for (int j = 0;j < limit; ++j) {
for (int k = 0;k < limit; ++k) {
c[j] = (c[j] + f[k] * vis[k][j]) % MOD;
}
}
memmove(f, c, sizeof c);
}
inline void mulself() {
ll c[1 << M][1 << M];
memset(c, 0, sizeof c);
for (int i = 0;i < limit; ++i) {
for (int j = 0;j < limit; ++j) {
for (int k = 0;k < limit; ++k) {
c[i][j] = (c[i][j] + vis[i][k] * vis[k][j]) % MOD;
}
}
}
memmove(vis, c, sizeof c);
}
int main(){
n = read(), m = read(), K = read();
limit = 1 << m;
cover = (1 << (m - 1)) - 1;
for (int i = 0;i < limit; ++i) {
int cnt = 0;
for (int j = 0;j < m; ++j) {
if (i & (1 << j)) ++cnt;
}
if (cnt <= K) jd[i] = 1;
}
for (int i = 0;i < limit; ++i) {
if (jd[i] == 0) continue;
memset(f, 0, sizeof f);
f[i] = 1;
memset(vis, 0, sizeof vis);
for (int j = 0;j < limit; ++j) {
if (jd[j] && jd[(j & cover) << 1]) vis[j][(j & cover) << 1] = 1;
if (jd[j] && jd[((j & cover) << 1) | 1]) vis[j][((j & cover) << 1) | 1] = 1;
}
ll x = n;
while (x) {
if (x & 1) mul();
mulself();
x >>= 1;
}
ans = (ans + f[i]) % MOD;
}
printf("%lld", ans);
return 0;
}