树状数组求逆序数

其实就是求冒泡排序的交换次数。

一个数列的逆序数等于 每一个数字前面比它大的数的个数和,比如 :1 4 2 3 5 的逆序数为:0+0+1+1+0=2;

初始化,数组bit={0};

比如数列 1 4 2 3 5

第一步:bit =  0 0 0 0 1  //把最大的元素位置赋值为1,并求其前面所有元素的和,为0

第二步:        0 1 0 0 1 //第二大元素的位置赋值为1,,求其前面所有元素的和,为0

第三步:        0 1 0 1 1 //...........为1

第四步:        0 1 1 1 1 //............为1

第五步:        1 1 1 1 1 //............为0



用树状数组可以高效求某一区间上的和,并对某一元素更新


#include <iostream>

using namespace std;
int n,a[20];
int bit[20];
int sum(int i)
{
    int s=0;
    while(i>0)
    {
        s+=bit[i];
        i-=i&-i;
    }
    return s;
}
void add(int i,int x)
{
    while(i<=n)
    {
        bit[i]+=x;
        i+=i&-i;
    }
}
void solve()
{
    int ans=0;
    for(int j=0;j<n;j++)
    {
        ans+=j-sum(a[j]);
        add(a[j],1);
    }
    cout<<ans<<endl;

}
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];

    solve();

    return 0;
}


原文地址:https://www.cnblogs.com/frankM/p/4399473.html