看 \(\ge X\) 不顺眼,怎么办呢!直接容斥!
钦定 \(j\) 个位置满足 \(|P_i - i| < X\),其余任意,就转化成了 [ARC132C] Almost Sorted。
具体一点就是,你设 \(f_{i, j, S}\) 表示前 \(i\) 位有 \(j\) 个位置满足 \(|P_i - i| < X\),然后 \(i - (X - 1) \sim i + (X - 1)\) 的覆盖情况为 \(S\)(状压),作用是你填 \(P_i\) 时知道哪些数已经被填过了。转移讨论是否钦定 \(|P_i - i| < X\) 即可,若钦定 \(|P_i - i| < X\) 还要枚举 \(P_i\)。注意一些边界的处理。
答案是 \(\sum\limits_{i = 0}^n \sum\limits_S f_{n, i, S} \times (-1)^i \times (n - i)!\),\((-1)^i\) 是容斥系数,还要乘 \((n - i)!\) 是因为除这 \(i\) 个数以外的所有数可以随便排。
时间复杂度 \(O(n^2 4^{X} X)\)。
code
// Problem: G - Ban Permutation
// Contest: AtCoder - Denso Create Programming Contest 2023 (AtCoder Beginner Contest 309)
// URL: https://atcoder.jp/contests/abc309/tasks/abc309_g
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair<ll, ll> pii;
const int maxn = 110;
const int mod = 998244353;
int n, m, f[maxn][maxn][maxn * 10];
ll fac[maxn];
inline void upd(int &x, int y) {
x += y;
(x >= mod) && (x -= mod);
}
void solve() {
scanf("%d%d", &n, &m);
fac[0] = 1;
for (int i = 1; i <= n; ++i) {
fac[i] = fac[i - 1] * i % mod;
}
--m;
f[0][0][0] = 1;
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < i; ++j) {
for (int S = 0; S < (1 << (m * 2 + 1)); ++S) {
if (!f[i - 1][j][S]) {
continue;
}
int T = (S >> 1);
upd(f[i][j][T], f[i - 1][j][S]);
for (int k = 0; k <= m * 2; ++k) {
if ((~T) & (1 << k)) {
if (i + k - m < 1 || i + k - m > n) {
continue;
}
upd(f[i][j + 1][T | (1 << k)], f[i - 1][j][S]);
}
}
}
}
}
ll ans = 0;
for (int i = 0; i <= n; ++i) {
for (int S = 0; S < (1 << (m * 2 + 1)); ++S) {
ll t = (i & 1) ? (mod - f[n][i][S]) : f[n][i][S];
ans = (ans + t * fac[n - i] % mod) % mod;
}
}
printf("%lld\n", ans);
}
int main() {
int T = 1;
// scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}
- Permutation Beginner AtCoder Contest 309beginner atcoder contest 309 permutation beginner atcoder contest permutation atcoder regular contest contest programming beginner atcoder beginner atcoder contest 296 beginner atcoder contest 295 beginner atcoder contest abcde beginner atcoder contest 335 beginner atcoder contest 332 beginner atcoder contest 328