POJ 2299 -- Ultra-QuickSort
阿新 • • 發佈:2018-02-10
亂序序列 blog app sea 次數 min 復雜 water 圖片 Ultra-QuickSort
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.
0 ≤ a[i] ≤ 999,999,999
解題:
1)利用歸並排序求逆序數
一個亂序序列的 逆序數 = 在只允許相鄰兩個元素交換的條件下,得到有序序列的交換次數
Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 65986 | Accepted: 24686 |
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 sequenceUltra-QuickSort produces the output
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
Source
Waterloo local 2005.02.05 題意: 輸入n個數,問至少經過多少次兩兩交換,可以得到一個升序序列 n < 500,000 -- the length of the input sequence註意保存逆序數的變量t,必須要用__int64定義,int一定會溢出的,而long long 在現在的VC編譯器已經無法編譯了。
註意__int64類型的輸出必須使用指定的c格式輸出,printf(“%I64d”,t);
cout是無法輸出__int64類型的
序列數組s[]用int就足夠了,每個元素都是小於10E而已
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int const maxa = 500005; 5 __int64 ans;//逆序數 6 int a[maxa];//存儲n個數 7 8 void Merge(int left,int mid,int right) 9 { 10 int len_l = mid-left+1; 11 int len_r = right-mid; 12 int* aLeft = new int[len_l+2]; 13 int* aRight = new int[len_r+2]; 14 for(int i=1;i<=len_l;i++) 15 aLeft[i] = a[left+i-1]; 16 aLeft[len_l+1] = 10000000000;//設置一個很大的上界防止溢出 17 for(int i=1;i<=len_r;i++) 18 aRight[i] = a[i+mid]; 19 aRight[len_r+1] = 10000000000;//設置一個很大的上界防止溢出 20 int m=1,n=1; 21 for(int i=left;i<=right;i++) 22 { 23 if(aLeft[m] <= aRight[n]) 24 { 25 a[i] = aLeft[m];m++; 26 } 27 else{ 28 ans+=len_l-m+1; 29 a[i] = aRight[n];n++; 30 } 31 } 32 delete aLeft; 33 delete aRight; 34 return; 35 36 } 37 38 void mergeSort(int left,int right) 39 { 40 if(left<right) 41 { 42 int mid = (left + right)/2; 43 mergeSort(left,mid); 44 mergeSort(mid+1,right); 45 Merge(left,mid,right); 46 } 47 return; 48 } 49 50 int main() 51 { 52 int n; 53 while(cin>>n && n!=0) 54 { 55 for(int i=1;i<=n;i++) 56 cin>>a[i]; 57 ans = 0; 58 mergeSort(1,n); 59 printf("%I64d\n",ans); 60 } 61 62 return 0; 63 }
為什麽要使用歸並呢?這是因為輸入的數據量可能會達到50W
下圖的測試是使用插入排序,不出意外的超時了
所以使用歸並排序,時間復雜度為O(nlogn)
只有堆排序和歸並排序時間復雜度可以控制在O(nlogn),因為他們都用用空間換時間,其他的排序算法在最壞的情況下,時間復雜度均為O(n^2)
2)樹狀數組
樹狀數組例題(poj2299)
樹狀數組詳細講解,不會算法也能看懂哦~
記錄一下,以後再學習……
POJ 2299 -- Ultra-QuickSort