zoukankan      html  css  js  c++  java
  • POJ 2299 Ultra-QuickSort 树状数组+离散化 求逆序对

    原题:http://poj.org/problem?id=2299

    解题思路:

    树状数组的参考资料:https://www.cnblogs.com/hsd-/p/6139376.html

    这里就不再赘述了。

    基本思路是将一组数据从大到小插入,然后累加每次插入时计算前面比它大的元素个数(即构成逆序),这里利用离散化+树状数组,每次插入时计算插入位置n之前的n-1项和即可

    输入数据同时记录下对应的数组下标,方便排序后将数据从大到小插入1。注意这里的“原数组”a[i]是不存在的,直接更新a[i]对应的树状数组即可

    以9 1 0 5 4 为例,插入1的数序是 9 5 4 1 0 的对应位置

    a[ ]起始为 0 0 0 0 0

    插入9后 1 0 0 0 0  ans +=  0

    插入5后 1 0 0 1 0   ans += 1

    插入4后 1 0 0 1 1   ans += 2 

    插入1后 1 1 0 1 1   ans += 1

    插入0后 1 1 1 1 1   ans += 2

    最后输出6

    代码如下

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 500010;
    
    struct T{
        int d; // data
        int id; //index
        bool operator < (const T& t) const{ //使原始数据按降序排序
            return d > t.d;
        }
    } b[maxn];
    
    int n;
    int c[maxn]; //树状数组
    int lowbit(int x)
    {
        return x&(-x);
    }
    
    void add(int x,int y)  //update c
    {
        for(int i = x; i <=n; i+=lowbit(i))
        {
            c[i] += y;
        }
    }
    
    int getSum(int x)  // get sum of a[1..x],求a数组的前x项和 
    {
        int sum = 0;
        for(int i = x; i >0; i -= lowbit(i))
            sum += c[i];
        return sum;
    }
    
    int main()
    {
        
        long long ans; // int型会溢出
        while(cin >> n && n)
        {
            memset(c,0,sizeof(c));
            ans = 0;
            for(int i = 1; i <= n; ++i)
            {
                cin >> b[i].d;
                b[i].id = i;
            }
            sort(b+1,b+n+1);
            for(int i = 1; i <= n; ++i)
            {
                int id = b[i].id;
                add(id,1); //注意这里省略了插入1到a数组的过程(因为用不上),直接更新c数组(树状数组)
                ans += getSum(id-1);
            }
            cout << ans << endl;
        }
        return 0;
    }
  • 相关阅读:
    42. Trapping Rain Water
    223. Rectangle Area
    645. Set Mismatch
    541. Reverse String II
    675. Cut Off Trees for Golf Event
    安装 VsCode 插件安装以及配置
    向上取整 向下取整 四舍五入 产生100以内随机数
    JS 判断是否为数字 数字型特殊值
    移动端初始配置,兼容不同浏览器的渲染内核
    Flex移动布局中单行和双行布局的区别以及使用
  • 原文地址:https://www.cnblogs.com/seanliao/p/8661320.html
Copyright © 2011-2022 走看看