[CF61E] Enemy is weak - 树状数组
Description
给定 n 个数的序列 a,求出满足 (i<j<k ,a_i > a_j > a_k) 的三元组 ((i,j,k)) 的个数
Solution
枚举中间位置 j,统计出左边更大的数的个数和右边更小的数的个数
离散化后权值树状数组即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
struct BinaryIndexTree
{
vector<int> a;
int n;
BinaryIndexTree(int siz)
{
n = siz;
a.resize(n + 2);
}
int lowbit(int x)
{
return x & (-x);
}
void Add(int p, int v)
{
while (p <= n)
{
a[p] += v;
p += lowbit(p);
}
}
int Sum(int p)
{
int ans = 0;
while (p)
{
ans += a[p];
p -= lowbit(p);
}
return ans;
}
int More(int p)
{
return Sum(n) - Sum(p);
}
int Less(int p)
{
return Sum(p - 1);
}
};
signed main()
{
ios::sync_with_stdio(false);
int n;
cin >> n;
vector<int> a(n + 2);
for (int i = 1; i <= n; i++)
cin >> a[i];
map<int, int> mp;
for (int i = 1; i <= n; i++)
mp[a[i]]++;
int ind = 0;
for (auto &[x, y] : mp)
y = ++ind;
for (int i = 1; i <= n; i++)
a[i] = mp[a[i]];
BinaryIndexTree bit_left(n), bit_right(n);
for (int i = 1; i <= n; i++)
bit_right.Add(a[i], 1);
int ans = 0;
for (int i = 1; i <= n; i++)
{
bit_left.Add(a[i], 1);
bit_right.Add(a[i], -1);
ans += bit_left.More(a[i]) * bit_right.Less(a[i]);
}
cout << ans << endl;
}