HDU2689 Sort it【树状数组】【逆序数】

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=2689


题目大意:

求把一个具有N个不同元素的序列通过交换两个相邻的元素转换成升序序列需要进行的交换次数

是多少。

例如:1 2 3 5 4,只需要交换5和4,交换次数为1次。


思路:

典型的求逆序数题。其实可以直接暴力过。但是用树状数组效率比较高。对于值为a第i个元素,

需要交换次数为前i个元素中大于a的元素个数,即逆序数。

用树状数组来做,数组Tree[i]表示数字i是否在序列中出现过,如果数字i已经存在于序列中,

Tree[i] = 1,否则Tree[i] = 0。按序列从左到右将值为a的元素当作下标为a,赋值为1插入树状

数组里,这时,比a的数个数就是i - Query(a)。将全部结果累加起来就是逆序数了。


AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 100010;

int N,Tree[MAXN];

int Lowbit(int i)
{
    return i & (-i);
}

void Update(int i,int x)
{
    while(i <= N)
    {
        Tree[i] = Tree[i] + x;
        i = i + Lowbit(i);
    }
}

int Query(int n)
{
    int sum = 0;
    while(n > 0)
    {
        sum += Tree[n];
        n = n - Lowbit(n);
    }
    return sum;
}

int main()
{
    while(cin >> N && N)
    {
        int a,ans = 0;
        memset(Tree,0,sizeof(Tree));
        for(int i = 1; i <= N; ++i)
        {
            cin >> a;
            Update(a,1);
            ans += i - Query(a);
        }
        cout << ans << endl;
    }

    return 0;
}


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。