序列、排列的全排列的逆序对

发布时间 2023-04-21 15:34:00作者: 晴屿

1.

题目大意:

给一个长度为n的的数组a,n是1到1e5,ai是1到1e5,问a的所有排序的序列的逆序对之和,会有重复的数字出现

题目链接:https://ac.nowcoder.com/acm/contest/46597/E

typedef long long ll;
typedef long long LL;
typedef pair<int,int> pii;
typedef unsigned long long ull;
typedef pair<double,double> pdd;
const int inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
#define endl '\n'
const int N = 1e5 + 7;
LL ksm(LL x, LL y) {
	LL res = 1;
	while (y) {
		if (y & 1) {
			res = 1ll * res * x % MOD;
		}
		x = 1ll * x * x % MOD;
		y >>= 1;
	}
	return res;
}
LL inv(int x) {
	return ksm(x, MOD - 2);
}
LL b[N], fac[N];
signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	int n;
	std::cin >> n;
	std::vector<LL>a(n + 1), s(n + 1), cnt(n + 1);
	for (int i = 1; i <= n; ++i) {
		std::cin >> a[i];
		b[i] = a[i];
	}
	if (n == 1) {
		std::cout << 0 << '\n';
		return 0;
	}
	std::sort(b + 1, b + 1 + n);
	int len = std::unique(b + 1, b + 1 + n) - b - 1;
	for (int i = 1; i <= n; ++i) {
		a[i] = std::lower_bound(b + 1, b + 1 + len, a[i]) - b;
		++cnt[a[i]];
	}
	fac[0] = 1;
	for (int i = 1; i <= n; ++i) {
		fac[i] = 1ll * fac[i - 1] * i % MOD;
	}
	LL ans = 0;
	for (int i = 1; i <= len; ++i) {
		s[i] = s[i - 1] + cnt[i];
	}
	for (int i = 1; i <= len; ++i) {
		ans = (ans + s[i - 1] * cnt[i]) % MOD;
	}
	std::cout << 1ll * ans * fac[n] % MOD * inv(2) % MOD << '\n';

	return 0;
}