[CF466D] Increase Sequence
Description
给定一个序列,可以对若干对区间 ([l,r]) 中的数 +(1)(每个区间只能加一次),且保证任意两个区间的左端点不重合,右端点不重合。最终要求序列中所有元素值都等于 (h),请输出总方案数对 (1e9+7) 取模后的结果。
Solution
遍历一遍,维护当前的区间个数 cnt 和答案 ans
如果 (a[i]-a[i-1]=1),那么当前必须新开一个区间
如果 (a[i]-a[i-1]=0),那么当前可以不动,也可以结束一个区间再新开一个区间
如果 (a[i]-a[i-1]=-1),那么当前必须关闭一个区间
否则,无法操作,游戏结束
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1000005;
const int mod = 1e9 + 7;
signed main()
{
ios::sync_with_stdio(false);
int n, h;
cin >> n >> h;
vector<int> a(n + 2);
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
a[i] = h - a[i];
int cnt = 0, ans = 1;
for (int i = n + 1; i >= 1; i--)
a[i] = a[i] - a[i - 1];
for (int i = 1; i <= n + 1; i++)
{
if (a[i] == 1)
++cnt;
else if (a[i] == 0)
ans *= cnt + 1, ans %= mod;
else if (a[i] == -1)
ans *= cnt, --cnt, ans %= mod;
else
{
cout << 0;
exit(0);
}
}
cout << ans;
}