码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-04-27 23:45:36      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:

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;
}


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

标签:

原文地址:http://blog.csdn.net/lianai911/article/details/45318265

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!