abc 252 d 题解
abc 252 d
题意
给定长度为 \(n\) 的序列 \(a = (a_1, a_2, \dots, a_n)\),请你求出满足以下条件的三元组的数量:
-
\(1 \le i < j < k \le n\)。
-
\(a_i, a_j, a_k\) 均不相同。
\(3 \le n \le 2 \times 10 ^ 5\)。
\(1 \le a_i \le 2 \times 10 ^ 5\)
思路
这道题目可以转换成这样:
求出满足 \(1 \le i, j, k \le n\) 且 \(a_i < a_j < a_k\) 的三元组数量。
那么,我们可以直接枚举中间的 \(a_j\) 的值。
令 \(s_i\) 表示在序列 \(a\) 中,小于等于 \(i\) 的数字数量,\(cnt_i\) 表示在序列 \(a\) 中,\(i\) 的出现次数,\(V\) 表示最大的 \(a_i\)。
那么对于每个 \(a_j\),它对答案的贡献就是 \(cnt_i \times s_{i - 1} \times (s_{V} - s_i)\)。
统计答案即可。
时间复杂度为 \(O(n + V)\),\(V\) 表示最大的 \(a_i\)。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10, INF = 2e5;
int n, a[N], cnt[N], s[N];
long long ans;
int main() {
ios::sync_with_stdio(0), cin.tie(0);
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
cnt[a[i]]++; // 统计出现次数
}
for (int i = 1; i <= INF; i++) {
s[i] = s[i - 1] + cnt[i]; // 前缀和
}
for (int i = 1; i <= INF; i++) {
ans += 1ll * cnt[i] * s[i - 1] * (s[INF] - s[i]); // 统计答案
}
cout << ans;
return 0;
}