国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

POJ 2299 Ultra-QuickSort (歸并排序、逆序數)

2019-11-08 02:22:32
字體:
來源:轉載
供稿:網友

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

59105431230

Sample Output

60

題意

求把一個序列排序所需要的最小相鄰交換次數。

思路

題目可以轉化為求數組所有數字的逆序數之和,因為n比較大的關系,所以舍棄 O(n2) 的算法,改用歸并排序。

一般這樣的題目都可以用歸并排序來解決,或者樹狀數組也可以。

假設當前歸并排序的兩個序列為

1 3 4 9

2 5 7 8

分別取數3、2,3>2,說明3后面所有的數都比2大(m-p),因為序列1一定在序列2前面,那這一個解釋便是逆序數咯!

另外,當序列2全部排序完之后序列1還剩9,此時可以得到,9以及后面的所有的數都比序列2大(y-m)。

AC 代碼

#include <iostream>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<map>#include<set>#include<algorithm>using namespace std;__int64 total,n;int A[500005],T[500005];void merge_sort(int x,int y){ if(y-x>1) { int m=x+(y-x)/2; int p=x,q=m,i=x; merge_sort(x,m); merge_sort(m,y); while(p<m&&q<y) { if(A[p]>A[q]) //說明A[p]后面的數都比A[q]大 { total+=m-p; T[i++]=A[q++]; } else { total+=q-m; //A[q]前面的都比A[p]小 T[i++]=A[p++]; } } while(q<y) { T[i++]=A[q++]; } while(p<m) { total+=y-m; //如果A[p]還有剩余,即剩下的都比A[q]大 T[i++]=A[p++]; } for(int j=x; j<y; j++) A[j]=T[j]; }}int main(int argc, char *argv[]){ while(~scanf("%I64d",&n)&&n) { memset(A,0,sizeof(A)); memset(T,0,sizeof(T)); total=0; for(int i=0; i<n; i++) scanf("%d",&A[i]); merge_sort(0,n); printf("%I64d/n",total/2); //除以2是因為計算了前面比i大,后面比i小的,也就是逆序數的二倍 } return 0;}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 乌审旗| 上思县| 左权县| 泰和县| 化隆| 汝南县| 和田县| 景东| 马边| 沾益县| 赞皇县| 肃南| 贺州市| 邹城市| 林口县| 锡林浩特市| 高邑县| 莒南县| 柞水县| 瑞金市| 乃东县| 宁安市| 阳新县| 兴城市| 兴业县| 琼结县| 遂宁市| 门头沟区| 临湘市| 桐梓县| 屏东市| 津南区| 天津市| 轮台县| 浑源县| 兰州市| 博爱县| 大同县| 永兴县| 伽师县| 新野县|