1、树状数组+离散化(nlogn)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cctype>
#define int long long
using namespace std;
const int N = 40010;
struct node {
int v,order;
};
int n,aa[N],c[N];
node a[N];
inline int read(){
int f=0,x=0;
char ch=getchar();
while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
return f?-x:x;
}
inline int lowbit(int x){
return x & -x;
}
inline void add(int x,int val){
for(;x<=n;x+=lowbit(x)){
c[x]+=val;
}
}
inline int getsum(int x){
int ans=0;
for(;x;x-=lowbit(x)){
ans+=c[x];
}
return ans;
}
inline bool cmp(node a,node b){
return a.v<b.v;
}
signed main(){
n=read();
for(int i=1;i<=n;++i){
a[i].v=read();
a[i].order=i;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;++i){
aa[a[i].order]=i;
}
int ans=0;
for(int i=1;i<=n;++i){
add(aa[i],1);
ans+=i-getsum(aa[i]);
}
printf("%lld",ans);
return 0;
}
2、归并排序(nlogn)
#include<cstdio>
#include<cstring>
#include<cctype>
#include<iostream>
#define N 40010
using namespace std;
int a[N],f[N],ans,n;
inline int read()
{
int f=0,x=0;
char ch=getchar();
while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
inline void merge(int l,int r){
if(l==r) return;
int mid=(l+r)>>1;
merge(l,mid);merge(mid+1,r);
int i=l,j=mid+1,p=l;
while(i<=mid&&j<=r){
if(a[i]>a[j]){
f[p++]=a[j++];
ans+=mid-i+1;
} else f[p++]=a[i++];
}
while(i<=mid) f[p++]=a[i++];
while(j<=r) f[p++]=a[j++];
for(int i=l;i<=r;i++) a[i]=f[i];
}
int main()
{
n=read();
for(int i=1;i<=n;i++) a[i]=read();
merge(1,n);
printf("%d",ans);
return 0;
}