码迷,mamicode.com
首页 > 其他好文 > 详细

Ultra-QuickSort POJ - 2299 (逆序对)

时间:2018-12-23 22:07:46      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:分享图片   +=   两种方法   roc   归并   art   div   printf   个数   

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

题意:将一个序列从小到大排序,如果只能交换相邻的数,最少需要交换多少次
思路:和冒泡排序一样,一个数需要交换的次数就是它的逆序对数,所以就是求总的逆序对的个数

求逆序对可以用两种方法
归并排序:
技术分享图片
 1 #include<cstdio>
 2 #include<iostream>
 3 using namespace std;
 4 
 5 int n;
 6 const int maxn = 5e5+5;
 7 int num[maxn];
 8 typedef long long ll;
 9 
10 ll Mersort(int l,int r)
11 {
12     int mid = (l+r)/2;
13     int i=l,j=mid+1;
14     int b[r-l+5];
15     int k=1;
16     ll ans = 0;
17     while(i <= mid && j <= r)
18     {
19         if(num[i] <= num[j])
20             b[k++] = num[i++];
21         else
22             b[k++] = num[j++],ans+=mid-i+1;
23     }
24     while(i <= mid)
25     {
26         b[k++] = num[i++];
27     }
28     while(j <= r)
29     {
30         b[k++] = num[j++];
31     }
32     for(int i=l; i<=r; i++)
33     {
34         num[i] = b[i-l+1];
35     }
36     return ans;
37 }
38 
39 int Merge(int l,int r,ll  &ans)
40 {
41     int mid = (l+r)/2;
42     if(l == r)
43         return 0;
44     Merge(l,mid,ans);
45     Merge(mid+1,r,ans);
46     ans += Mersort(l,r);
47 }
48 int main()
49 {
50     while(~scanf("%d",&n) && n)
51     {
52         for(int i=1; i<=n; i++)
53             scanf("%d",&num[i]);
54         ll  ans = 0;
55         Merge(1,n,ans);
56         printf("%lld\n",ans);
57     }
58 }
View Code

 


树状数组:(要注意离散,离散可以二分,也可以map)
技术分享图片
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<string.h>
 5 using namespace std;
 6 
 7 const int maxn = 5e5+5;
 8 int n;
 9 int tree[maxn];
10 typedef long long ll;
11 
12 int lowbit(int x)
13 {
14     return x&(-x);
15 }
16 
17 void add(int x)
18 {
19     for(int i=x;i<=n;i+=lowbit(i))
20     {
21         tree[i]++;
22     }
23 }
24 
25 int Query(int x)
26 {
27     int ans = 0;
28     for(int i=x;i>0;i-=lowbit(i))
29     {
30         ans+=tree[i];
31     }
32     return ans;
33 }
34 int query(int x,int n,int *b)
35 {
36     return lower_bound(b+1,b+1+n,x) - b;
37 }
38 int main()
39 {
40     while(~scanf("%d",&n) && n)
41     {
42         memset(tree,0,sizeof(tree));
43         int a[n+1],b[n+1];
44         for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i] = a[i];
45         sort(b+1,b+1+n);
46         int len = unique(b+1,b+1+n)-b-1;
47         ll ans = 0;
48         for(int i=1;i<=n;i++)
49         {
50             int pos = query(a[i],len,b);
51             add(pos);
52             ans +=  pos - 1 - Query(pos-1);
53         }
54         printf("%lld\n",ans);
55     }
56 }
View Code

 



Ultra-QuickSort POJ - 2299 (逆序对)

标签:分享图片   +=   两种方法   roc   归并   art   div   printf   个数   

原文地址:https://www.cnblogs.com/iwannabe/p/10165562.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!