代码:
# include <bits/stdc++.h>
# include <atcoder/modint>
using mint = atcoder :: modint998244353;
using namespace std;
# define ll long long
# define ull unsigned long long
# define rep(i, f, t, ...) for (int i = f, ##__VA_ARGS__; i <= t; ++i)
# define red(i, f, t, ...) for (int i = f, ##__VA_ARGS__; i >= t; --i)
# define emb emplace_back
# define pb push_back
# define pii pair<int, int>
# define mkp make_pair
# define arr3 array<int, 3>
# define arr4 array<int, 4>
# define FILEIO(filename) freopen (filename".in", "r", stdin), freopen (filename ".out", "w", stdout)
# define N 3005
template < class T > constexpr static T inf = numeric_limits < T > :: max ( ) / 2;
bool Mst;
int n, p[N], cnt = 0, ivcnt = 0, P[N], V[N];
mint dp[N][3];
const static mint IV2 = 998244353 + 1 >> 1;
const static mint IV6 = ( unsigned ) ( ( 998244353 + 1 ) / 6 );
bool Med;
signed main() {
ios_base :: sync_with_stdio ( false ), cin.tie ( nullptr ), cout.tie (nullptr);
cin >> n; rep (i, 1, n) cin >> p[i], cnt += ( p[i] == -1 );
rep (i, 1, n) rep (j, i + 1, n) ivcnt += ( ~p[i] && ~p[j] && p[i] > p[j] );
fill ( P + 1, P + n + 1, 1 );
fill ( V + 1, V + n + 1, 1 );
rep (i, 1, n) if ( ~ p[i] ) P[i] = V[p[i]] = 0;
rep (i, 1, n) P[i] += P[i - 1], V[i] += V[i - 1];
dp[0][0] = 1;
rep (i, 1, n) {
mint s1 = i * ( i - 1 ) / 2;
mint s2 = 1ll * i * ( i - 1 ) * ( 2 * i - 1 ) * IV6;
dp[i][0] = dp[i - 1][0] * i;
dp[i][1] = dp[i - 1][0] * s1 + dp[i - 1][1] * i;
dp[i][2] = dp[i - 1][0] * s2 + dp[i - 1][1] * s1 * 2 + dp[i - 1][2] * i;
}
mint s1 = 0, s01 = 0, s11 = 0;
rep (i, 1, n) if ( ~ p[i] ) s1 += 1ll * P[i] * ( cnt - V[p[i]] ) + ( cnt - P[i] ) * V[p[i]];
if ( cnt >= 2 ) {
rep (i, 1, n) if ( ~ p[i] ) {
s01 += P[i] * ( P[i] - 1 ) * IV2 * ( cnt - V[p[i]] ) * ( cnt - V[p[i]] - 1 ) * IV2 + ( cnt - P[i] ) * ( cnt - P[i] - 1 ) * IV2 * V[p[i]] * ( V[p[i]] - 1 ) * IV2;
s01 += ( P[i] * ( P[i] - 1 ) * IV2 + P[i] * ( cnt - P[i] ) ) * ( ( cnt - V[p[i]] ) * ( cnt - V[p[i]] - 1 ) * IV2 + V[p[i]] * ( cnt - V[p[i]] ) );
s01 += ( ( cnt - P[i] ) * ( cnt - P[i] - 1 ) * IV2 + P[i] * ( cnt - P[i] ) ) * ( V[p[i]] * ( V[p[i]] - 1 ) * IV2 + V[p[i]] * ( cnt - V[p[i]] ) );
}
s01 = s01 * dp[cnt - 2][0] + s1 * dp[cnt - 1][1];
mint res1 = 0, res2 = 0; // res1 : same res2 : diff
rep (i, 1, n) rep (j, i, n) if ( ~ p[i] && ~ p[j] ) {
auto & s = ( i == j ? res1 : res2 );
s += P[i] * ( cnt - P[j] ) * ( ( cnt - V[p[i]] ) * V[p[j]] - max ( V[p[j]] - V[p[i]], 0 ) );
s += P[i] * ( P[j] - 1 ) * ( ( cnt - V[p[i]] ) * ( cnt - V[p[j]] ) - ( cnt - max ( V[p[i]], V[p[j]] ) ) );
s += ( cnt - P[j] ) * ( cnt - P[i] - 1 ) * ( V[p[i]] * V[p[j]] - min ( V[p[i]], V[p[j]] ) );
s += ( P[j] * ( cnt - P[i] ) - ( P[j] - P[i] ) ) * ( ( cnt - V[p[j]] ) * V[p[i]] - max ( V[p[i]] - V[p[j]], 0 ) );
}
s11 += ( res1 + res2 * 2 ) * dp[cnt - 2][0];
}
if ( cnt >= 1 ) {
mint res1 = 0, res2 = 0;
rep (i, 1, n) rep (j, i, n) if ( ~ p[i] && ~ p[j] ) {
auto & s = ( i == j ? res1 : res2 );
s += P[i] * ( cnt - max ( V[p[i]], V[p[j]] ) );
s += ( P[j] - P[i] ) * max ( V[p[i]] - V[p[j]], 0 );
s += ( cnt - P[j] ) * min ( V[p[i]], V[p[j]] );
}
s11 += ( res1 + res2 * 2 ) * dp[cnt - 1][0];
}
mint ans = dp[cnt][2] + dp[cnt][1] * ivcnt * 2 + dp[cnt][0] * ivcnt * ivcnt;
ans += ( cnt >= 1 ? s1 * dp[cnt - 1][0] * ivcnt * 2 : 0 ) + s01 * 2 + s11;
cout << ans.val ( ) << endl;
# ifdef MACOS
cerr << "Memory & Time Information : " << endl;
cerr << "Memory : " << ( ( &Med ) - ( &Mst ) ) * 1. / 1024. / 1024. << "MB" << endl;
cerr << "Time : " << clock ( ) * 1. / CLOCKS_PER_SEC * 1000. << "ms" << endl;
# endif
return 0;
}
如果能给一组比较小的hack数据也可以。谢谢!