CF1096F.Inversion Expectation[树状数组+概率期望] Educational Codeforces Round 57

给一个排列(有些是-1,代表等概率是没出现过数字中的任意一个),求期望逆序对个数

分成三部分(x表示已知)

  • -1和-1之间的
  • -1和x之间的
  • x和x之间的

具体柿子在下面

```cpp
// -1 -1 cnt * (cnt - 1) / 2 / 2
// -1 x cnt(-1) * cnt(-1) / cnt(-1)
// x -1 cnt(-1) * cnt(-1) / cnt(-1)
// x x

int a[MAXN], n, gt[MAXN], ls[MAXN], cnt[MAXN]; //cnt[i] [1..i]-1的个数 gt[i] 比 i 大的-1个数 | ls[i] 比 i 小的-1个数
bool vis[MAXN];

struct BIT {
int t[MAXN];
inline void add(int k, int v) {
while (k <= n) t[k] += v, k += k & -k;
}
inline int query(int k) {
int ret = 0;
while (k) ret += t[k], k -= k & -k;
return ret;
}
} bit;
// a[i] -> gt[1,a[i]-1]
// a[i] -> ls[a[i]+1,n]

int main() {
int ans = 0, tmp = 0;
in, n;
lop1(i, n) {
in, a[i];
if (~a[i]) vis[a[i]] = 1, bit.add(a[i], 1), ans += ++tmp - bit.query(a[i]), Mod(ans, mod);
else cnt[i] = 1;

}
// out, ans, '\n';
lop1(i, n) {
cnt[i] += cnt[i-1];
if (!vis[i]) ++gt[1], --gt[i], ++ls[i + 1];//, --ls[n + 1];
}
ans += cnt[n] * 1ll * (cnt[n] - 1) % mod * Pow(4, mod-2, mod) % mod;
Mod(ans, mod);
lop1(i, n) gt[i] += gt[i-1], ls[i] += ls[i-1];
int Inv = Pow(cnt[n], mod - 2, mod);
lop1(i, n)
if (~a[i]) {
int x = ls[a[i]] * 1ll * (cnt[n] - cnt[i - 1]) % mod + gt[a[i]] * 1ll * cnt[i - 1] % mod;
Mod(x, mod);
ans += x * 1ll * Inv % mod;
Mod(ans, mod);
}
out, ans;
return 0;
}
```C

猜你喜欢

转载自www.cnblogs.com/storz/p/10229444.html