Ultra-QuickSort
Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 14909 | Accepted: 5253 |
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.
Ultra-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
题解:题目实际上就是求逆序数,由于n最多只有500000,所以首先离散化。
然后用树状数组解决:就是扫描原序列,累加在其前面且大于它的个数。
1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4 #include <algorithm>
5
6 using namespace std;
7 const int N = 500010;
8 int n;
9 int a[N];
10 int C[N];
11 int ori[N];
12 int index;
13 int lowbit(int x)
14 {
15 return x & (-x);
16 }
17 int getSum(int x)
18 {
19 int tot = 0;
20 while(x>0)
21 {
22 tot += C[x];
23 x -= lowbit(x);
24 }
25 return tot;
26 }
27 void update(int x,int delta)
28 {
29 while(x<N)
30 {
31 C[x]+=delta;
32 x += lowbit(x);
33 }
34 }
35 int b_search(int val)
36 {
37 int l = 2,r = index;
38 while(l<r)
39 {
40 int m = l+(r-l)/2;
41 if(val==a[m])return m;
42 if(val<a[m])r= m;
43 else l = m+1;
44 }
45 return -1;
46 }
47 int main()
48 {
49 while(scanf("%d",&n)!=EOF&&n!=0)
50 {
51 memset(C,0,sizeof(C));
52 for(int i=2;i<=n+1;i++)
53 {
54 scanf("%d",a+i);
55 ori[i] = a[i];
56 }
57 sort(a+2,a+2+n);
58 index = 3;
59 for(int i=2;i<=n;i++)
60 {
61 if(a[i]!=a[i+1])
62 {
63 a[index++] = a[i+1];
64 }
65 }
66 long long ans = 0;
67 update(b_search(ori[2]),1);
68 for(int i=3;i<=n+1;i++)
69 {
70 int t = b_search(ori[i]);
71 ans+= getSum(index+1) - getSum(t);
72 update(t,1);
73 }
74 printf("%lld\n",ans);
75 }
76 return 0;
77 }
78
3 #include <cstdio>
4 #include <algorithm>
5
6 using namespace std;
7 const int N = 500010;
8 int n;
9 int a[N];
10 int C[N];
11 int ori[N];
12 int index;
13 int lowbit(int x)
14 {
15 return x & (-x);
16 }
17 int getSum(int x)
18 {
19 int tot = 0;
20 while(x>0)
21 {
22 tot += C[x];
23 x -= lowbit(x);
24 }
25 return tot;
26 }
27 void update(int x,int delta)
28 {
29 while(x<N)
30 {
31 C[x]+=delta;
32 x += lowbit(x);
33 }
34 }
35 int b_search(int val)
36 {
37 int l = 2,r = index;
38 while(l<r)
39 {
40 int m = l+(r-l)/2;
41 if(val==a[m])return m;
42 if(val<a[m])r= m;
43 else l = m+1;
44 }
45 return -1;
46 }
47 int main()
48 {
49 while(scanf("%d",&n)!=EOF&&n!=0)
50 {
51 memset(C,0,sizeof(C));
52 for(int i=2;i<=n+1;i++)
53 {
54 scanf("%d",a+i);
55 ori[i] = a[i];
56 }
57 sort(a+2,a+2+n);
58 index = 3;
59 for(int i=2;i<=n;i++)
60 {
61 if(a[i]!=a[i+1])
62 {
63 a[index++] = a[i+1];
64 }
65 }
66 long long ans = 0;
67 update(b_search(ori[2]),1);
68 for(int i=3;i<=n+1;i++)
69 {
70 int t = b_search(ori[i]);
71 ans+= getSum(index+1) - getSum(t);
72 update(t,1);
73 }
74 printf("%lld\n",ans);
75 }
76 return 0;
77 }
78