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

    题目就是让你求逆序数,用树状数组很简单,不过数据太大,要先进行离散化,将数据范围压缩到1~n以内。还有poj竟然不支持c++11,害得我lambda表达式编译错误。


    #include <iostream>
    #include <sstream>
    #include <fstream>
    #include <string>
    #include <map>
    #include <vector>
    #include <list>
    #include <set>
    #include <stack>
    #include <queue>
    #include <deque>
    #include <algorithm>
    #include <functional>
    #include <iomanip>
    #include <limits>
    #include <new>
    #include <utility>
    #include <iterator>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <cmath>
    #include <ctime>
    using namespace std;
    
    const int maxn = 500010;
    int bit[maxn], n;
    
    struct ST
    {
        int num, index;
    };
    
    ST a[maxn];
    
    //树状数组求和
    int sum(int i)
    {
        int s = 0;
        while (i > 0)
        {
            s += bit[i];
            i &= i - 1;
        }
        return s;
    }
    
    //树状数组修改元素
    void add(int i, int x)
    {
        while (i <= n)
        {
            bit[i] += x;
            i += i & (-i);
        }
    }
    
    int main()
    {
        while (scanf("%d", &n) == 1 && n)
        {
            memset(bit, 0, sizeof(bit));
            for (int i = 0; i < n; ++i)
            {
                scanf("%d", &a[i].num);
                a[i].index = i;
            }
    
            //离散化
            sort(a, a+n, [](ST a, ST b){ return a.num < b.num; });
            int cnt = 0, tmp;
            for (int i = 0; i < n; ++i)
                if (!i || a[i].num != tmp)
                {
                    tmp = a[i].num;
                    a[i].num = ++cnt;
                }
                else
                {
                    tmp = a[i].num;
                    a[i].num = cnt;
                }
            sort(a, a+n, [](ST a, ST b){ return a.index < b.index; });
    
            //树状数组求逆序数
            long long ans = 0;
            for (int i = 0; i < n; ++i)
            {
                ans += i - sum(a[i].num);
                add(a[i].num, 1);
            }
            cout << ans << endl;
        }
        return 0;
    }
    


  • 相关阅读:
    Linux下端口被占用确认
    Debuggex – 超好用的正则表达式可视化调试工具
    URL最大长度
    无需重启 修改计算机名直接生效
    UDP穿越NAT原理(p2p)
    gdb中信号
    锁 (读写锁优先级 写饥饿) (锁竞争引发的高系统调用)
    Loopback接口用途---用作管理地址。
    C/C++调试:gdbserver的简单使用
    总结一下NDK crash排查步骤
  • 原文地址:https://www.cnblogs.com/godweiyang/p/12203962.html
Copyright © 2011-2022 走看看