Fork me on GitHub

逆序对

https://www.luogu.org/problem/show?pid=1908

这里写图片描述
做法:O(nlogn)
每次加入一个数,把当前输入进的数中比这个数大的数求和,用树状数组b来维护,b[i]表示的是
i~i+lowbit(i) 的个数和,每输入进一个数,就把b数组更新.

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int n,maxn,ans;
int a[40009],b[9999999];
void add(int x)
{
    for(int i=x;i>=1;i-=(i& (-i)))
     b[i]++;
}
int sum(int x)
{
    int t=0;
    for(int i=x;i<=maxn;i+=(i& (-i)))
     t+=b[i];
    return t;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        maxn=max(a[i],maxn);
        add(a[i]);
        ans+=sum(a[i]+1);//用树状数组求a[i]+1 ~ maxn 的个数和 
    }
    printf("%d",ans);
    return 0;
}
posted @ 2017-09-24 17:48  primes  阅读(100)  评论(0编辑  收藏  举报