#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define N 500000 + 10
#define ll long long
int n;
int b[N], c[N];
struct A {
int val, id;
bool operator < (const A &b) const {
return val < b.val;
}
} a[N];
int lowbit(int x)
{
return x & (-x);
}
void toTree(int i,int a)
{
while (i <= n) {
c[i] += a;
i += lowbit(i);
}
}
int sum(int i)
{
int ans = 0;
while (i) {
ans += c[i];
i -= lowbit(i);
}
return ans;
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i].val;
a[i].id = i; // id存储输入顺序
}
sort(a + 1,a + n + 1);
b[a[1].id] = 1;
for(int i = 2; i <= n; i++) {
// b[i]存储数字在序列中的相对位置(从小到大排),相同数字的相对位置一样
if(a[i].val == a[i - 1].val) b[a[i].id] = b[a[i - 1].id];
else b[a[i].id] = i;
}
ll ans = 0;
for(int i = 1; i <= n; i++) {
toTree(b[i],1);
ans += i - sum(b[i]);
}
cout << ans << endl;
return 0;
}
树状数组+离散化 可处理重复数字
于 2019-06-04 13:58:17 首次发布