poj2299(树状数组+离散化)

这道题题意很简单,就是求逆序数。用暴力的方法是显然会超时的。这里考虑采用树状数组。

采用树状数组话遇到的问题就是需要999,999,999个空间来存放数据,这显然是不可行的。考虑到输入数据最多只有500,000个,那么可以采用离散化的方法来先将输入数据进行映射到较小的空间上,然后再用一般的树状数组操作统计即可。

#include <cstdio>
#include <algorithm>
using namespace std;

const int MAX = 500005;
struct Node{
    int v;
    int order;
}node[MAX];
int num[MAX];
int tree[MAX];

int sum(int idx){
    int ans = 0;
    while (idx > 0){
        ans += tree[idx];
        idx -= idx&-idx;
    }
    return ans;
}

void update(int idx, int val)
{
    while (idx <= MAX)
    {
        tree[idx] += val;
        idx += idx&-idx;
    }
}

bool cmp(Node n1, Node n2)
{
    return n1.v < n2.v;
}

int main()
{
    int n;
    while (scanf("%d", &n) != EOF && n){
        memset(tree, 0, sizeof(tree));
        memset(node, 0, sizeof(node));
        //离散化开始
        for (int i = 1; i <= n; i++){
            scanf("%d", node + i);
            node[i].order = i;
        }
        sort(node + 1, node + n + 1, cmp);
        for (int i = 1; i <= n; i++){
            num[node[i].order] = i;
        }
        //离散化完成,以下为一般的树状数组操作
        long long inverseNo = 0;
        for (int i = 1; i <= n; i++){
            inverseNo += (i - 1) - sum(num[i]);
            update(num[i], 1);
        }
        printf("%lld\n", inverseNo);
    }
    return 0;
}

 参考:

http://www.cnblogs.com/shenshuyang/archive/2012/07/14/2591859.html

https://www.topcoder.com/community/data-science/data-science-tutorials/binary-indexed-trees/

posted on 2015-10-23 12:16  caiminfeng  阅读(1546)  评论(0编辑  收藏  举报

导航