zoukankan      html  css  js  c++  java
  • POJ2299 Ultra-QuickSort(树状数组求逆序数+离散化)

    原文:http://blog.csdn.net/alongela/article/details/8142965

    给定n个数,要求这些数构成的逆序对的个数。除了用归并排序来求逆序对个数,还可以使用树状数组来求解。

    树状数组求解的思路:开一个能大小为这些数的最大值的树状数组,并全部置0。从头到尾读入这些数,每读入一个数就更新树状数组,查看它前面比它小的 已出现过的有多少个数sum,然后用当前位置减去该sum,就可以得到当前数导致的逆序对数了。把所有的加起来就是总的逆序对数。

    题目中的数都是独一无二的,这些数最大值不超过999999999,但n最大只是500000。如果采用上面的思想,必然会导致空间的巨大浪费,而 且由于内存的限制,我们也不可能开辟这么大的数组。因此可以采用一种称为“离散化”的方式,把原始的数映射为1-n一共n个数,这样就只需要500000 个int类型的空间。

    离散化的方式:

    struct Node

    {

    int val;

    int pos;

    };

    Node node[500005];

    int reflect[500005];

    val存放原数组的元素,pos存放原始位置,即node[i].pos = i。

    把这些结构体按照val的大小排序。

    reflect数组存放离散化后的值,即reflect[node[i].pos] = i。

    这样从头到尾读入reflect数组中的元素,即可以保持原来的大小关系,又可以节省大部分空间。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int N = 500005;
    struct Node
    {
        int val;
        int pos;
    };
    Node node[N];
    int c[N], reflect[N], n;
    bool cmp(const Node& a, const Node& b)
    {
        return a.val < b.val;
    }
    int lowbit(int x)
    {
        return x & (-x);
    }
    void update(int x)
    {
        while (x <= n)
        {
            c[x] += 1;
            x += lowbit(x);
        }
    }
    int getsum(int x)
    {
        int sum = 0;
        while (x > 0)
        {
            sum += c[x];
            x -= lowbit(x);
        }
        return sum;
    }
    int main()
    {
        while (scanf("%d", &n) != EOF && n)
        {
            for (int i = 1; i <= n; ++i) 
            {
                scanf("%d", &node[i].val);
                node[i].pos = i;
            }
            sort(node + 1, node + n + 1, cmp);   //排序
            for (int i = 1; i <= n; ++i) reflect[node[i].pos] = i;   //离散化
            for (int i = 1; i <= n; ++i) c[i] = 0;   //初始化树状数组
            long long ans = 0;
            for (int i = 1; i <= n; ++i)
            {
                update(reflect[i]);
                ans += i - getsum(reflect[i]);
            }
            printf("%lld
    ", ans);
        } 
        return 0;
    }
  • 相关阅读:
    Redux React-redux 理解
    React ---- 浅谈ReactJs
    javascript --- 鼠标事件
    javaScript --- localStorage 本地存储
    javascript -- 对象(深拷贝、浅拷贝)
    javascript --- 数组输出数组中最大值最小值差值
    Css中未知 div 宽高度,水平垂直居中方法
    Windows下使用NCL(Cygwin模拟Linux环境)
    Qt加载网页(加载浏览器插件)和制作托盘后台运行(南信大财务报账看号)
    OpenGL超级宝典第5版&&GLSL法线变换
  • 原文地址:https://www.cnblogs.com/d-e-v-i-l/p/4782910.html
Copyright © 2011-2022 走看看