/**************
思路 建立 一个树状数组 初始化 每一位 都为 1 (表示每个数都存在)
讲 序列 输入 a 结构体数组中 一个变量存数 一个存原位置
从大到小排序
然后 for 最大——最小:
查询最大的那个数 后面区间有几个数存在 就表示有几个 逆序数
然后删除最大的这个数。
****************/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#define ll long
#include<algorithm>
using namespace std;
const int maxn = 5e5;
struct node
{
ll num;
int id;
}
a[maxn];
bool cmp(node x, node y)
{
return x.num > y.num;
}
ll c[maxn];
ll n;
ll lowbit(ll x)
{
return x&(-x);
}
void update(ll i, ll k)
{
while(i <= n)
{
c[i]+=k;
i += lowbit(i);
}
}
ll getsum(ll i)
{
ll res= 0;
while(i >= 1)
{
res+= c[i];
i-=lowbit(i);
}
return res;
}
ll sum(ll l, ll r)
{
return getsum(r)-getsum(l-1);
}
int main()
{
while(~scanf("%ld", &n)&&n)
{
memset(c, 0, sizeof(c));
for(int i = 1; i <= n; i++)
{
scanf("%ld", &a[i].num);
a[i].id = i;
update(i, 1);
}
sort(a+1, a+n+1 ,cmp);
long long cnt = 0;
for(int i = 1; i <= n; i++)
{
cnt+= sum(a[i].id+1 , n);
update(a[i].id, -1);
}
printf("%lld\n", cnt);
}
}
02-05
2856