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 sequence 
9 1 0 5 4 ,
Ultra-QuickSort produces the output 
0 1 4 5 9 .
Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.

Input

The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.

Output

For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.

Sample Input

5
9
1
0
5
4
3
1
2
3
0

Sample Output

6
0
解题思路:题意很简单,树状数组or归并排序求逆序数,这里只讲树状数组的实现!因为a[i]的值高达10^9,树状数组的大小肯定开不了这么大,而n最大为5e5(可作为数组大小,不过大小还要再开大一点,避免越界),因此需要将原来每个元素离散化,即重新编个号(1~n)。
做法:用一个结构体记录原来每个元素val出现的次序id,然后将结构体按val的大小升序排序,接下来遍历排序后的结构体数组,将原来的元素离散化成1~n,即将id对应原来的数字改成第i大(i∈[1,n]),最后就可以直接用树状数组进行更新和统计逆序数了。
拿题目中9 1 0 5 4这个样例来加强对数据离散化的理解:
输入的元素值 9 1 0 5 4 -->排序后 0 1 4 5 9
对应的次序id 1 2 3 4 5 3 2 5 4 1
此时将排序后每个id对应的元素离散化成第i小即 1 2 3 4 5,显然0是第1小,且是第3次出现,1是第2小,且是第2次出现...
这样我们就已经成功地把原来的数据离散化,接下来遍历一下次序id:tar[1]=5(原来为9,9是第一个输入的,这里就变成了5,空间上压缩了不少),先在树状数组中标记为1,并且5前面有4个空为0,于是5(9)这个元素构成了4个逆序对,累加逆序数4并继续按此操作下去即可找出所有的逆序数。
AC代码:
 #include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=;
typedef long long LL;
int n,val,aa[maxn],tar[maxn];
struct node{int val,id;}nod[maxn];
bool cmp(node a,node b){return a.val<b.val;}
int lowbit(int x){
return x & -x;
}
void update(int x,int val){
while(x<=n){
aa[x]+=val;
x+=lowbit(x);
}
}
int getsum(int x){
int ret=;
while(x>){
ret+=aa[x];
x-=lowbit(x);
}
return ret;
}
int main(){
while(cin>>n&&n){
LL ans=;
memset(aa,,sizeof(aa));//注意清空
for(int i=;i<=n;++i){
cin>>nod[i].val;
nod[i].id=i;//记录元素val出现的次序id
}
sort(nod+,nod+n+,cmp);//然后数组元素val按升序排序
for(int i=;i<=n;++i)tar[nod[i].id]=i;//离散化数据:tar[nod[i].id]表示原来第nod[i].id次出现的值换成现在1~n中的编号i
for(int i=;i<=n;++i){
update(tar[i],);//tar[i]表示为输入值的次序:第i次出现的值(已离散化),先将该值在树状数组中标记为1,表示该数字已出现
ans+=tar[i]-getsum(tar[i]);//求出tar[i]前面还没出现数字的个数即为与当前tar[i]构成逆序对的个数,然后累加即可
}
cout<<ans<<endl;
}
return ;
}

题解报告:poj 2299 Ultra-QuickSort(BIT求逆序数)的更多相关文章

  1. poj 2299 Ultra-QuickSort :归并排序求逆序数

    点击打开链接 Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 34676   Accepted ...

  2. poj 2299 树状数组求逆序数+离散化

    http://poj.org/problem?id=2299 最初做离散化的时候没太确定可是写完发现对的---由于后缀数组学的时候,,这样的思维习惯了吧 1.初始化as[i]=i:对as数组依照num ...

  3. POJ 2299 -Ultra-QuickSort-树状数组求逆序数

    POJ 2299Ultra-QuickSort 使用树状数组记录逆序对数. 把数组按照大小顺序插入,getsum(i)就是i前面的比他大的数. #include <cstdio> #inc ...

  4. poj 2299 树状数组求逆序对数+离散化

    Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 54883   Accepted: 20184 ...

  5. POJ 2299树状数组求逆序对

    求逆序对最常用的方法就是树状数组了,确实,树状数组是非常优秀的一种算法.在做POJ2299时,接触到了这个算法,理解起来还是有一定难度的,那么下面我就总结一下思路: 首先:因为题目中a[i]可以到99 ...

  6. Ultra-QuickSort POJ - 2299 树状数组求逆序对

    In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a seque ...

  7. poj 2299 Ultra-QuickSort (归并排序 求逆序数)

    题目:http://poj.org/problem?id=2299 这个题目实际就是求逆序数,注意 long long 上白书上的模板 #include <iostream> #inclu ...

  8. POJ 2299 Ultra-QuickSort 归并排序、二叉排序树,求逆序数

    题目链接: http://poj.org/problem?id=2299 题意就是求冒泡排序的交换次数,显然直接冒泡会超时,所以需要高效的方法求逆序数. 利用归并排序求解,内存和耗时都比较少, 但是有 ...

  9. poj 2299 Ultra-QuickSort(树状数组求逆序数)

    链接:http://poj.org/problem?id=2299 题意:给出n个数,求将这n个数从小到大排序,求使用快排的需要交换的次数. 分析:由快排的性质很容易发现,只需要求每个数的逆序数累加起 ...

随机推荐

  1. Meteor结构

    Meteor提供了一些特殊的文件夹,可以帮助开发人员构建他们的应用程序. client 如果创建客户端文件夹,这个文件夹里面的一切都将在客户端上运行.在这里,可以将您的HTML,CSS和客户端Java ...

  2. Material UI:很强大的CSS框架

    Material UI 是一款功能很强大,界面却十分清新简洁的CSS框架.Material UI利用了Google的Material Design 全新设计语言.而且让每个UI组件都变得很独立.因此开 ...

  3. vue 自定义报警组件

    1.自定义报警组件 Alarm.vue <!-- 报警 组件 --> <template> <div class="alarm"> <!- ...

  4. 基于空间直方图meanshift跟踪

    近期看了一篇文章<spatiograms versus histograms for region-based tracking>,在此把这篇文章的核心思想及算法推理进行整理. 空间直方图 ...

  5. sdut 面向对象程序设计上机练习四(变量引用)

    面向对象程序设计上机练习四(变量引用) Time Limit: 1000MS Memory limit: 65536K 题目描写叙述 将变量的引用作为函数形參,实现2个int型数据交换. 输入 输入2 ...

  6. 一张图理清js原型链(通过内置对象的引用关系)

    很多同学估计写了几年js也没有搞清内置对象之间的原型链关系,鄙人抽空手绘了一张简图,以作参考: 简单说明一下,上图中annonymous()函数相当于是所有函数的根(它本身也是函数),他上面提供了一些 ...

  7. 局域网内PC通过笔记本共享上网

    现实:PC.笔记本都通过网线接在局域网内,局域网无法上网:笔记本有无线网卡,可连WIFI上网. 现在想让PC通过笔记本来共享上网. 步骤: 1.笔记本开启DHCP.方法是开启"服务" ...

  8. 2016/04/13 ①html 中各种分割线------------------------------------------ ② 控制文字显示

    ①各种分割线Html代码 1.<HR> 2.<HR align=center width=300 color=#987cb9 SIZE=1>align 线条位置(可选left. ...

  9. linux 监控进程所消耗的资源(内存),达到阈值(绝对值、相对值)后,将其杀死

    监控某个python进程是否存在,如不存在则启动 #!/bin/bashwhile [ 1 ]do #打印出当前的jboss进程:grep jboss查询的jboss进程,grep -v " ...

  10. POJ1679 The Unique MST —— 次小生成树

    题目链接:http://poj.org/problem?id=1679 The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total S ...