对低于某个具体的序列,计算:

  • AA 等于所有前缀的最小值之和
  • BB 等于所有后缀的最小值之和
  • CC 等于序列最小值

则其「自由度」为:

A+B2nC+nA + B - 2nC + n

对于一个带有 00 的序列,设其最小正项为 ww00ss 个,则其实际最小值不小于 i (iw)i\ (i \le w) 的方案数为:

(Vi+1)s(V - i + 1) ^ s

利用拉格朗日插值快速计算 i=1xis\displaystyle\sum _{i = 1} ^x i^s,时间复杂度为 O(n2)O(n^2),空间复杂度为 O(n2)O(n^2)

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int P = 1e9 + 7;
int divs(int a, int b, int p)
{
	if (b % a == 0) return b / a;
	int x = divs(p % a, a - b % a, a);
	return (x * p + b) / a;
}
int power(int x, int y)
{
	if (y == 0) return 1;
	if (y == 1) return x;
	int c = power(x, y >> 1);
	c = c * c % P;
	if (y & 1) c = c * x % P;
	return c;
}
const int N = 1000, NN = N + 12;
int a[NN], p[NN][NN], q[NN][NN], fc[NN], pd1[NN], pd2[NN];
void init()
{
	fc[0] = 1;
	for (int i = 1; i <= N + 2; i++)
		fc[i] = fc[i - 1] * i % P;
	for (int i = 1; i <= N; i++)
		for (int j = 1; j <= i + 2; j++)
		{
			p[i][j] = p[i][j - 1] + power(j, i);
			if (p[i][j] >= P) p[i][j] -= P;
			q[i][j] = p[i][j] * divs(fc[j - 1] * fc[i + 2 - j] % P, 1, P) % P;
			if ((i + 2 - j) & 1) q[i][j] = P - q[i][j];
			if (q[i][j] == P) q[i][j] = 0;
		}
}
int sum(int x, int y)
{
	if (!x) return y;
	if (y <= x + 2) return p[x][y];
	for (int i = 0; i <= x + 3; i++)
		pd1[i] = pd2[i] = 0;
	pd1[0] = pd2[x + 3] = 1;
	for (int i = 1; i <= x + 2; i++)
		pd1[i] = pd1[i - 1] * (y - i) % P;
	for (int i = x + 2; i >= 1; i--)
		pd2[i] = pd2[i + 1] * (y - i) % P;
	int ans = 0;
	for (int i = 1; i <= x + 2; i++)
	{
		ans += pd1[i - 1] * pd2[i + 1] % P * q[x][i] % P;
		if (ans >= P) ans -= P;
	}
	return ans;
}
int sum(int l, int r, int x)
{
	int ans = sum(x, r) - sum(x, l - 1);
	if (ans < 0) ans += P;
	return ans;
}
int solve(int n, int V, int s)
{
	int t = 0, w = V, ans = 0;
	for (int i = 1; i <= n; i++)
	{
		if (!a[i]) t++;
		if (a[i]) w = min(w, a[i]);
		ans += sum(V - w + 1, V, t) * power(V, s - t) % P;
	}
	return ans % P;
}
signed main()
{
	init();
	int n, V, s = 0, w = 1e9;
	cin >> n >> V;
	w = V;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
		if (!a[i]) s++;
		if (a[i]) w = min(w, a[i]);
	}
	int ans = n * (power(V, s) - 2 * sum(V - w + 1, V, s) + 2 * P) % P;
	ans += solve(n, V, s);
	reverse(a + 1, a + n + 1);
	ans += solve(n, V, s);
	cout << ans % P << endl;
	return 0;
}