求逆序对(树状数组)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=5e5+5;
int t[maxn],a[maxn],n,tot;
long long ans;
inline long long rd(){
register int x=0,f=0;register char ch=getchar();
while(ch<‘0‘||ch>‘9‘)f|=ch==‘-‘,ch=getchar();
while(ch>=‘0‘&&ch<=‘9‘)x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return f?-x:x;
}
void A(int x,int a){
for(;x<=n;x+=x&-x)t[x]+=a;
}
int Q(int x){
int ans=0;
for(;x;x-=x&-x)ans+=t[x];
return ans;
}
struct Node{
int id,data;
}node[maxn];
bool cmp(Node a,Node b){
return a.data<b.data;
}
int main(){
// freopen("1.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;++i){
node[i].data=rd();
node[i].id=i;
}
sort(node+1,node+1+n,cmp);//离散化
for(int i=1;i<=n;++i){
if(node[i].data>node[i-1].data){//赋予其小点的数,我们只需要知道其相对位置即可
a[node[i].id]=i;
}else a[node[i].id]=a[node[i-1].id];//处理相等情况,离散化为一个数值
}
for(int i=n;i>=1;--i){
ans+=(long long)Q(a[i]-1);
A(a[i],1);
}
printf("%lld\n",ans);
return 0;
}
原文:https://www.cnblogs.com/Lour688/p/13229554.html