逆序对
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ls u<<1
#define rs u<<1|1
#define mid ((l+r)>>1)
#define LL long long
const int N=500005;
int n,m,a[N],b[N];
int sum[N<<2];
void pushup(int u)
{
sum[u]=sum[ls]+sum[rs];
}
void change(int u,int l,int r,int x)
{//x其实就是位置序号
if(l==r)
{
sum[u]++;
return;
}
if(x<=mid) change(ls,l,mid,x);
else change(rs,mid+1,r,x);
pushup(u);
}
LL query(int u,int l,int r,int x,int y)
{
if(x<=l&&r<=y) return sum[u];
LL s=0;
if(x<=mid) s+=query(ls,l,mid,x,y);
if(y>mid) s+=query(rs,mid+1,r,x,y);
return s;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
b[i]=a[i];
}
sort(b+1,b+1+n);
LL s=0;
for(int i=1;i<=n;i++)
{
//这一个就是离散化,把数字本身转化为排序序号就可以了
int id=lower_bound(b+1,b+n+1,a[i])-b;
//在数组b的索引1到n范围内查找第一个大于或等于a[i]的元素位置,然后将返回的指针转换为数组索引
change(1,1,n,id);//其实就是建线段树
s+=query(1,1,n,id+1,n);//id右面的数是先插入且大于id的数
}
cout<<s<<endl;
}