1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| #include <bits/stdc++.h> using namespace std; typedef long long ll; const int mod = 1e9 + 7, inv2 = (mod + 1) / 2; const int N = 200010; int n, a[N], cnt[N], tot = 1, ans; int tr[2][N * 4];
inline int add(const int &x, const int &y) { return x + y < mod ? x + y : x + y - mod; } inline int sub(const int &x, const int &y) { return x - y < 0 ? x - y + mod : x - y; } inline int mul(const int &x, const int &y) { return (int)((ll)x * y % mod); } int ksm(int x, int y = mod - 2) { int ss = 1; for(; y; y >>= 1, x = mul(x, x)) if(y & 1) ss = mul(ss, x); return ss; } void build(int u, int l, int r) { if(l >= r) { tr[0][u] = cnt[l] - (n - l), tr[1][u] = cnt[l] - (n - l + 1); return ; } int mid = (l + r) >> 1; build(u * 2, l, mid), build(u * 2 + 1, mid + 1, r); tr[0][u] = mul(tr[0][u * 2], tr[0][u * 2 + 1]); tr[1][u] = mul(tr[1][u * 2], tr[1][u * 2 + 1]); } int ask(int u, int l, int r, int L, int R, int w) { if(L <= l && r <= R) return tr[w][u]; int mid = (l + r) >> 1, res = 1; if(L <= mid) res = mul(res, ask(u * 2, l, mid, L, R, w)); if(R > mid) res = mul(res, ask(u * 2 + 1, mid + 1, r, L, R, w)); return res; } int main() { scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]), ++cnt[a[i]]; for(int i = n; i; i--) cnt[i] += cnt[i + 1]; for(int i = n; i; i--) tot = mul(tot, sub(cnt[i], n - i)); if(!tot) { puts("0"); return 0; } build(1, 1, n); for(int i = 1; i < n; i++) for(int j = i + 1; j <= n; j++) { if(a[i] == a[j]) ans = add(ans, mul(tot, inv2)); else if(a[i] < a[j]) { int ss = mul(tot, ksm(ask(1, 1, n, a[i] + 1, a[j], 0))); ss = mul(ss, ask(1, 1, n, a[i] + 1, a[j], 1)); ans = add(ans, mul(ss, inv2)); } else { int ss = mul(tot, ksm(ask(1, 1, n, a[j] + 1, a[i], 0))); ss = mul(ss, ask(1, 1, n, a[j] + 1, a[i], 1)); ss = sub(tot, mul(ss, inv2)), ans = add(ans, ss); } } printf("%d\n", ans); return 0; }
|