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

版权声明:本文为博主原创文章,转载请注明出处。

时间: 2024-10-05 23:39:24

poj2299(Ultra-QuickSort)树状数组+离散化的相关文章

POJ2299 Ultra-QuickSort 【树状数组】+【hash】

Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 39529   Accepted: 14250 Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swappin

HDU 2227 Find the nondecreasing subsequences (DP+树状数组+离散化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2227 Find the nondecreasing subsequences                                  Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)                                             

BZOJ 1227 [SDOI2009] 虔诚的墓主人 离线+树状数组+离散化

鸣谢:140142耐心讲解缕清了我的思路 题意:由于调这道题调的头昏脑涨,所以题意自己搜吧,懒得说. 方法:离线+树状数组+离散化 解析:首先深表本蒟蒻对出题人的敬(bi)意(shi).这道题简直丧心病狂,看完题后大脑一片空白,整个人都不好了,刚开始的思路是什么呢?暴力思想枚举每个墓碑,然后计算每个墓碑的虔诚度,然后再来统计.不过看看数据范围呢?10^9*10^9的矩阵,最多才10^5个树,光枚举就已经超时了,所以肯定不行.(不过要是考试真没思路我就那么搞了- -!) 然后也想到来枚举墓碑,不过

求逆序数模板(树状数组+离散化 || 归并排序法)

一篇不错的讲解:http://www.cnblogs.com/shenshuyang/archive/2012/07/14/2591859.html 代码如下:(树状数组+离散化) #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn=500017; int n; int aa[maxn

Ultra-QuickSort (树状数组离散化)

题目原意是用归并排序,刚学树状数组,就用了下 树状数组的离散化 离散化,是数据范围太大是所借用的利器,举个例子,有四个数99999999 1 123 1583 数据范围太大,而树状数组中的c数组开的范围是数据的范围,这时候就需要离散化,把四个数一次标号为1 2 3 4(即第一个数,第二个数...),按键值排序之后 依次为2 3 4 1(即从小到大排序为第二个数,第三个数...),所以,第二个数是最小的,即f[2]=1,f[3]=2,f[4]=3,f[1]=4,也就是把键值变为了1~n,相对大小还

hdu4325 树状数组+离散化

http://acm.hdu.edu.cn/showproblem.php?pid=4325 Problem Description As is known to all, the blooming time and duration varies between different kinds of flowers. Now there is a garden planted full of flowers. The gardener wants to know how many flower

高桥低桥(树状数组离散化)

1335: 高桥和低桥 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 362  Solved: 62 [Submit][Status][Web Board] Description 有个脑筋急转弯是这样的:有距离很近的一高一低两座桥,两次洪水之后高桥被淹了两次,低桥却只被淹了一次,为什么?答案是:因为低桥太低了,第一次洪水退去之后水位依然在低桥之上,所以不算"淹了两次".举例说明: 假定高桥和低桥的高度分别是5和2,初始水位为1 第一次

Ultra-QuickSort(树状数组 + 离散化)

Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input seque

POJ2299 Ultra-QuickSort(树状数组求逆序数+离散化)

原文:http://blog.csdn.net/alongela/article/details/8142965 给定n个数,要求这些数构成的逆序对的个数.除了用归并排序来求逆序对个数,还可以使用树状数组来求解. 树状数组求解的思路:开一个能大小为这些数的最大值的树状数组,并全部置0.从头到尾读入这些数,每读入一个数就更新树状数组,查看它前面比它小的 已出现过的有多少个数sum,然后用当前位置减去该sum,就可以得到当前数导致的逆序对数了.把所有的加起来就是总的逆序对数. 题目中的数都是独一无二

poj2299(树状数组+离散化)

这道题题意很简单,就是求逆序数.用暴力的方法是显然会超时的.这里考虑采用树状数组. 采用树状数组话遇到的问题就是需要999,999,999个空间来存放数据,这显然是不可行的.考虑到输入数据最多只有500,000个,那么可以采用离散化的方法来先将输入数据进行映射到较小的空间上,然后再用一般的树状数组操作统计即可. #include <cstdio> #include <algorithm> using namespace std; const int MAX = 500005; st