LPA20020220
2018-12-19 13:53:55
提供一个复杂度为
证明已经基本上告诉我们了, 如果可以达到下界, 那么最长下降子序列的长度不能超过
那么设
把
那么如果加上字典序限制怎么办呢?类似数位
例如下面这个例子:
假设我们现在在考虑
这个方案数怎么算? 就是这道题......预处理逆元, 阶乘即可
另外, 注意如果我们强制卡满限制, 填数也是需要满足上面我们
代码如下:
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <algorithm>
#define R register
#define IN inline
#define W while
#define gc getchar()
#define MX 1205000
#define MOD 998244353ll
#define ll long long
template <class T>
IN void in(T &x)
{
x = 0; R char c = gc;
for (; !isdigit(c); c = gc);
for (; isdigit(c); c = gc)
x = (x << 1) + (x << 3) + c - 48;
}
template <class T> IN T max(T a, T b) {return a > b ? a : b;}
int fac[MX], inv[MX], bd[MX];
bool used[MX];
IN void pre()
{
fac[0] = fac[1] = inv[0] = inv[1] = 1;
for (R int i = 2; i <= 1200000; ++i)
{
fac[i] = 1ll * fac[i - 1] * i % MOD;
inv[i] = 1ll * inv[MOD % i] * (MOD - MOD / i) % MOD;
}
for (R int i = 2; i <= 1200000; ++i) inv[i] = 1ll * inv[i] * inv[i - 1] % MOD;
}
IN int C(R int n, R int m)
{
if (n < m) return 0;
return 1ll * fac[n] * inv[m] % MOD * inv[n - m] % MOD;
}
int main(void)
{
int T, n, lim, mn, mx, ans; pre(), in(T);
W (T--)
{
in(n); mx = ans = 0, mn = 1;
std::memset(used, false, sizeof(bool) * (n + 1));
for (R int i = 1; i <= n; ++i) in(bd[i]);
for (R int i = 1; i <= n; ++i)
{
lim = max(mx + 1, bd[i] + 1); used[bd[i]] = true;
if (lim <= n)
(ans += ((C(2 * n - i - lim + 1, n - i + 1) - C(2 * n - i - lim + 1, n - i + 2) + MOD) % MOD)) %= MOD;
if (mx < bd[i]) mx = bd[i];
else if (bd[i] != mn) break;
W (used[mn]) ++mn;
}
printf("%d\n", ans);
}
}