Ultra-QuickSort POJ - 2299 (逆序对)

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

 



posted @ 2018-12-23 20:47  进击的黑仔  阅读(254)  评论(0编辑  收藏  举报