设为首页 加入收藏

TOP

poj 2299 Ultra-QuickSort 求逆序数,树状数组解法,详细解析
2015-07-20 17:20:08 来源: 作者: 【 】 浏览:3
Tags:poj 2299 Ultra-QuickSort 序数 解法 详细 解析
Ultra-QuickSort
Time Limit: 7000MS Memory Limit: 65536K
Total Submissions: 44554 Accepted: 16195

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 sZ??http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcnRlZCBpbiBhc2NlbmRpbmcgb3JkZXIuIEZvciB0aGUgaW5wdXQgc2VxdWVuY2UgPGJyPgo8Y2VudGVyPjkgMSAwIDUgNCAsPC9jZW50ZXI+Cjxicj4KVWx0cmEtUXVpY2tTb3J0IHByb2R1Y2VzIHRoZSBvdXRwdXQgPGJyPgo8Y2VudGVyPjAgMSA0IDUgOSAuPC9jZW50ZXI+Cjxicj4KWW91ciB0YXNrIGlzIHRvIGRldGVybWluZSBob3cgbWFueSBzd2FwIG9wZXJhdGlvbnMgVWx0cmEtUXVpY2tTb3J0IG5lZWRzIHRvIHBlcmZvcm0gaW4gb3JkZXIgdG8gc29ydCBhIGdpdmVuIGlucHV0IHNlcXVlbmNlLgo8cCBjbGFzcz0="pst">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
 
 
我的AC状态:	\
 
 
	哈哈,时间连题目要求的十分之一都没到,我对树状数组还是很满意的。
	我先简单的说下树状数组求逆序数的方法,先逆序数定义:点击打开链接
看完逆序数的定义,首先从定义上看,我们其实可以转换一下,有一个序列An,假设其中第i数它后面有Ci比他小的,那逆序数就等于C=C1+C2+...Ci+...Cn,他其实就等价于假设其中第i个数,他前面有Di个比他大的数,D=D1+D2+...+Di+...+Dn=C。这个很容易理解的,相信大家都可以看懂。
接下来大家可能认为结束了,很显然,没结束,想一下树状数组的结构,如果求一个数前面有多少个比他大的,他得一直从1一直遍历到无穷。想想都可怕,所以我们得再转换一下,我们是否可以先求出前i个数中有多少个不大于第i个数的呢?这个很简单,我们只要遍历1->i,就解决了,那好,总共有i个数,假设在它前面有x个不大于第i数的,那比第i个数的大的自然不就出来了么,不就等于i-x-1吗?
	好了,分析到这里,我想大家都应该明白了,我得申明一下,树状数组不能直接求一个含有小于等于0的数的序列的逆序数,
至于为什么不能有负数,你想想,数组的下标能有负的吗?至于为什么不能有0,那是因为树状数组的有个0陷阱,这个自己百度,不多说了。
	不能直接求,但我们可以间接求啊,至于怎么求,我只简单的说一下,转换坐标轴的原点不就可以了吗!!假设10000>Ai>-10000,我们就可以把Ai+10000,得到20000
  

   
好的,下面是我的代码:


   
#include 
     
      
#include 
      
        #define MAX 1001000 int t[MAX]; int lowbit(int x) { return x&(-x) ; } void update(int pos) { while(pos
       
        0) { count += t[pos] ; pos -= lowbit(pos) ; } return count ; } int main() { int n; while(~scanf("%d",&n) && n) { memset(t,0,sizeof(t)) ; long long sum = 0 ; for(int i = 0 ; i < n ; ++i) { int temp ; scanf("%d",&temp) ; int count = query(temp+1) ; //防止树状数组的0陷阱 sum += i-count ; update(temp+1) ; } printf("%I64d\n",sum) ; } return 0 ; }
       
      
     

你看,,,是不是比归并排序求逆序数少很多代码,也更容易理解了!
辛辛苦苦码这么多字,,大家多支持一下啦
转载请标明出处
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Leetcode_Compare Version Numbers 下一篇poj 2481 Cows 树状数组解法,详细..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·【C语言】动态内存管 (2025-12-27 06:23:20)
·C语言中的内存管理 - (2025-12-27 06:23:16)
·C语言指南:C语言内 (2025-12-27 06:23:14)
·Redis on AWS:Elast (2025-12-27 04:19:30)
·在 Spring Boot 项目 (2025-12-27 04:19:27)