模板:
int n; int tree[LEN]; int lowbit(int x){ return x&-x; } void update(int i,int d){//index,delta while(i<=n){ tree[i]+=d; i+=lowbit(i); } } int getsum(int i){ int ans=0; while(i>0){ ans+=tree[i]; i-=lowbit(i); } return ans; }
示意图:
大佬代码:

//树状数组 #include<iostream> #include<string.h> #include<algorithm> using namespace std; #define MAX 500010 int c[MAX]; int aa[MAX]; int n; typedef struct nano{ int val; int order; }node; node in[MAX]; int lowbit(int x) { return x&(-x); } void update(int x,int val) { while(x<=n){ c[x]+=val; x+=lowbit(x); } } int sum(int x) { int s=0; while(x>=1) { s+=c[x]; x-=lowbit(x); } return s;//一开始竟然忘记写了这个语句,还以为树状数组写错了呢 } bool cmp(node a,node b){ return a.val<b.val; } int main(int argc, char *argv[]) { //freopen("2299.in", "r", stdin); while(scanf("%d",&n)==1&&n){ for(int i=1;i<=n;++i) { scanf("%d",&in[i].val); in[i].order=i; } sort(in+1,in+n+1,cmp); for(int i=1;i<=n;++i) aa[in[i].order]=i;//离散化到小范围来 memset(c,0,sizeof(c)); long long ans=0; for(int i=1;i<=n;++i) { update(aa[i], 1); ans+=(i-sum(aa[i])); } printf("%lld\n",ans); } return 0; }
大佬代码理解:
首先用结构体node:{val,order} 来存输入信息,用sort(in+1,in+n+1,cmp); 来根据val值进行排序,通过代码
for(int i=1;i<=n;++i) aa[in[i].order]=i;
构造数组aa,aa表示第i个数排第aa[i]位。(代码理解:i表示原本的索引,in[i].order表示排序后的索引)
逆序数计算:
for(int i=1;i<=n;++i) { update(aa[i], 1); ans+=(i-sum(aa[i])); }
ans增量: 索引i之前比他大的数。