Froginald the frog
矩阵快速幂
如果没有分隔的话,这就是一个矩阵快速幂求斐波那契的问题
因为有分隔,因此考虑他们分成若干个块,每个块的方案数之积就是答案,显然分隔的长度如果大于 \(1\),则答案为 \(0\)
有点小卡常,所以如果是比较小的斐波那契询问,直接打表
或者是加个记忆化
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 10;
const ll mod = 1e9 + 7;
ll init[10100];struct node
{ll array[maxn][maxn];int x, y;node(){x = 0, y = 0;}node(int _x, int _y) {x = _x; y = _y;}void init(int a){for(int i=1; i<=x; i++)for(int j=1; j<=y; j++)array[i][j] = (i == j) * a;}node operator *(const node& a) const{node ans(x, a.y);ans.init(0);for(int i=1; i<=x; i++){for(int j=1; j<=a.y; j++){for(int k=1; k<=y; k++){ans.array[i][j] += array[i][k] * a.array[k][j] % mod;}ans.array[i][j] %= mod;}}return ans;}
};node qpow(node x, int n)
{node ans(x.x, x.y);ans.init(1);while(n){if(n & 1) ans = ans * x;n >>= 1;x = x * x;}return ans;
}ll F(ll n)
{if(n < 10100) return init[n];node x(2, 2);x.init(0);x.array[1][1] = x.array[1][2] = x.array[2][1] = 1;x = qpow(x, n - 2);node ans(2, 1);ans.array[1][1] = ans.array[2][1] = 1;ans = x * ans;return ans.array[1][1];
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int n, m;cin >> n >> m;init[2] = init[1] = 1;for(int i=3; i<10100; i++)init[i] = (init[i - 1] + init[i - 2]) % mod;vector<int>num(m + 1);for(int i=1; i<=m; i++) cin >> num[i];num[0] = n + 1;sort(num.begin(), num.end());ll ans = 1, pre = 0;for(int i=0; i<num.size(); i++){if(num[i] == pre) {ans = 0; break;}ans = ans * F(num[i] - pre) % mod;pre = num[i] + 1;}cout << ans << endl;return 0;
}