树状数组|求逆序数

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#define ll long long
#define maxn 100005
using namespace std;
int c[maxn],n;
int low_bit(int i)
{
    return i&(-i);
}

void update(int i,int v)
{
    while(i<=n){
        c[i]+=v;
        i+=low_bit(i);
    }
}

int getsum(int i)
{
    int res=0;
    while(i){
        res+=c[i];
        i-=low_bit(i);
    }
    return res;
}

int main()
{
//	5
//	5 3 4 2 1 
    while(scanf("%d",&n),n)
    {
        memset(c,0,sizeof(c));
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            int a;
            scanf("%d",&a);
            update(a,1);//向上更新:因为树状数组维护的是比当前值a小的数的个数  当前输入a 比a大的值后面就更新加1 update是向上更新 
            int ttt = getsum(a);
            ans+=i-ttt;//求逆序 已经有i个数了 减去这i个数比a小的数的个数(树状数组维护的值) 
        }
        for(int j=0;j<n;j++){
        	cout<<c[j]<<" ";
        } 
        cout<<endl;
        printf("%d\n",ans);
    }
    return 0;
}

几道例题:

蓝桥杯 小朋友排队(树状数组+逆序数)
Problem - 4911 (树状数组+离散化)
牛客多校算法A 裸题:https://ac.nowcoder.com/acm/contest/77/A

posted @ 2019-03-01 16:24  fishers  阅读(250)  评论(0编辑  收藏  举报