题目大意
给定一个序列,求其中三元上升子序列的个数
- 对于 ,若 ,则是一个满足要求的三元对。
分析
考虑枚举中间的数 ,设其左边有 个数比它小,右边有 个数比它大,则中间为 的三元对个数为 。
至此就和逆序对类似了,离散化后用树状数组即可。
#include "template/ds/fwtree/0.hpp"
int main() {
int n = rr();
vector<pii> v(n + 1);
for (int i = 1; i <= n; i++) {
v[i] = {rr(), i};
}
sort(v.begin(), v.end(), [](pii a, pii b) {
if (a.first == b.first)
return a.second > b.second;
return a.first < b.first;
});
fwtree_1<int> tr(n + 1);
vector<ll> al(n + 1), ar(n + 1);
for (int i = 1; i <= n; i++) {
al[i] = tr.sum(1, v[i].second);
tr.add(v[i].second, 1);
}
tr = fwtree_1<int>(n + 1);
for (int i = n; i >= 1; i--) {
ar[i] = tr.sum(v[i].second, n);
tr.add(v[i].second, 1);
}
ll ans = 0;
for (int i = 1; i <= n; i++)
ans += 1ll * al[i] * ar[i];
printf("%lld\n", ans);
return 0;
}