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
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
正解一:归并排序
解题报告:
大概题意是求数列的冒泡排序排序次数,求逆序对的模板题。
直接归并排序的时候统计一下就可以了。
归并排序的提交记录:
1 //It is made by jump~ 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <algorithm> 8 #include <ctime> 9 #include <vector> 10 #include <queue> 11 #include <map> 12 #include <set> 13 #ifdef WIN32 14 #define OT "%I64d" 15 #else 16 #define OT "%lld" 17 #endif 18 using namespace std; 19 typedef long long LL; 20 const int MAXN = 500011; 21 int n,m; 22 int jump[MAXN]; 23 int g[MAXN]; 24 LL ans; 25 26 inline int getint() 27 { 28 int w=0,q=0; 29 char c=getchar(); 30 while((c<'0' || c>'9') && c!='-') c=getchar(); 31 if (c=='-') q=1, c=getchar(); 32 while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); 33 return q ? -w : w; 34 } 35 36 inline void merge(int l,int mid,int r){ 37 int i=l,j=mid+1; 38 int cnt=l; 39 while(i<=mid && j<=r) { 40 if(jump[i]<=jump[j]) g[cnt++]=jump[i++]; 41 else{ 42 g[cnt++]=jump[j++]; 43 //ans+=mid-i+1; 44 ans+=(LL)mid; ans-=(LL)i; ans++; 45 } 46 } 47 while(i<=mid) g[cnt++]=jump[i++]; 48 while(j<=r) g[cnt++]=jump[j++]; 49 //for(;i<=mid;i++) g[cnt++]=a[i]; 50 //for(;j<=r;j++) g[cnt++]=a[i]; 51 for(i=l;i<=r;i++) jump[i]=g[i]; 52 } 53 54 inline void gui(int l,int r){ 55 if(l==r) return ; 56 int mid=(l+r)/2; 57 gui(l,mid); gui(mid+1,r); 58 merge(l,mid,r); 59 } 60 61 inline void solve(){ 62 while(1) { 63 n=getint(); 64 if(n==0) break; 65 for(int i=1;i<=n;i++) jump[i]=getint(); 66 ans=0; 67 gui(1,n); 68 printf(OT" ",ans); 69 } 70 } 71 72 int main() 73 { 74 solve(); 75 return 0; 76 }
正解二:树状数组
解题报告:
树状数组也是可做的。
由于数字比较大,先离散化一下,然后按顺序插入,插入之后看看已经有多少个数比自己大了,统计一下就可以了。
比归并排序慢好多哦。。。
Run ID | User | Problem | Result | Memory | Time | Language | Code Length | Submit Time |
15602746 | ljh2000 | 2299 | Accepted | 7932K | 532MS | G++ | 1256B | 2016-06-10 15:41:43 |
1 //It is made by jump~ 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <algorithm> 8 #include <ctime> 9 #include <vector> 10 #include <queue> 11 #include <map> 12 #include <set> 13 #ifdef WIN32 14 #define OT "%I64d" 15 #else 16 #define OT "%lld" 17 #endif 18 using namespace std; 19 typedef long long LL; 20 const int MAXN = 500011; 21 int n,L; 22 LL ans; 23 int a[MAXN],u[MAXN]; 24 int shu[MAXN],rank[MAXN]; 25 26 inline int getint() 27 { 28 int w=0,q=0; 29 char c=getchar(); 30 while((c<'0' || c>'9') && c!='-') c=getchar(); 31 if (c=='-') q=1, c=getchar(); 32 while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); 33 return q ? -w : w; 34 } 35 36 inline void update(int x,int val){ 37 while(x<=L) { 38 shu[x]+=val; 39 x+=x&(-x); 40 } 41 } 42 43 inline LL query(int x){ 44 LL total=0; 45 while(x>0) { 46 total+=shu[x]; 47 x-=x&(-x); 48 } 49 return total; 50 } 51 52 inline void solve(){ 53 while(1) { 54 n=getint(); 55 if(n==0) break; 56 for(int i=1;i<=n;i++) u[i]=a[i]=getint(); 57 ans=0; 58 memset(shu,0,sizeof(shu)); 59 sort(u+1,u+n+1); 60 L=unique(u+1,u+n+1)-u-1; 61 for(int i=1;i<=n;i++) { 62 rank[i]=lower_bound(u+1,u+L+1,a[i])-u; 63 update(rank[i],1); 64 ans+=query(L)-query(rank[i]); 65 } 66 67 printf(OT" ",ans); 68 } 69 } 70 71 int main() 72 { 73 solve(); 74 return 0; 75 }