题目大意:
求长度为 (n) 的排列,逆序对个数小于等于 (k) 的排列个数。
正文:
设 (f_{i,j}) 表示前 (i) 位有 (j) 个逆序对的方案数,由于第 (i) 位能为前 (i-1) 位贡献,动态转移方程是:
[f_{i,j}=sum_{l=0}^{i-1}f_{i-1,j-l}
]
但这个时间复杂度是 (O(nk^2)),我们要开一个前缀和,顺便滚动一下,确保时空都不会超。
代码:
ll n, k;
ll f[4][N], ans, sum;
int main()
{
scanf ("%lld%lld", &n, &k);
f[1][0] = 1LL;
for (ll i = 2; i <= n; i++)
{
sum = 0LL;
for (ll j = 0; j <= k; j++)
{
if(i <= j) sum = (sum - f[(i - 1) & 1][j - i] + mod) % mod;
sum = (sum + f[(i - 1) & 1][j]) % mod;
f[i&1][j] = sum;
}
}
for (int i = 0; i <= k; i++)
ans = (ans + f[n & 1][i]) % mod;
printf("%lld", ans);
return 0;
}