标签:
归并排序 (求逆序数)
归并排序:递归+合并+排序
时间复杂度:O(n logn) 空间复杂度:O(n)
用途:1.排序 2.求逆序对数
Description
Input
Output
Sample Input
5 9 1 0 5 4 3 1 2 3 0
Sample Output
6 0
题意:
给出长度为n的无序序列,每次只能交换相邻的两个数,求至少要交换多少次才使得该序列为递增序列。
分析:
1.根据时间范围估计时间复杂度,归并排序的时间复杂度一般为O(n logn)
2.算法步骤: 1.划分问题:把序列分为元素个数尽量相等的两半
2.递归求解:把两半元素分别排序
3.合并问题:把两个有序表合成一个
3.保存时,用long long 类型,否则会wa的
代码:
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 const int maxn=500001; 5 6 int a[maxn],b[maxn]; 7 long long ans; 8 9 void merge(int l,int m,int r) //归并排序 10 { 11 int i=l,j=m+1,t=0; 12 while(i<=m&&j<=r) //从小到大排序 13 { 14 if(a[i]>a[j]) 15 { 16 b[t++]=a[j++]; 17 ans+=m-i+1; 18 } 19 else b[t++]=a[i++]; 20 } 21 while(i<=m) 22 b[t++]=a[i++]; 23 while(j<=r) 24 b[t++]=a[j++]; 25 for(int i=0;i<t;i++) //合并 26 a[l+i]=b[i]; 27 } 28 29 void merge_sort(int l,int r) //划分问题 30 { 31 if(l<r) 32 { 33 int m=(l+r)/2; 34 merge_sort(l,m); 35 merge_sort(m+1,r); 36 merge(l,m,r); 37 } 38 } 39 40 int main() 41 { 42 int n; 43 while(scanf("%d",&n)!=EOF) 44 { 45 if(n==0) 46 break; 47 ans=0; 48 for(int i=0;i<n;i++) 49 scanf("%d",&a[i]); 50 merge_sort(0,n-1); 51 printf("%lld\n",ans); 52 } 53 return 0; 54 }
本来想着完全不看别人的代码都由自己做,可是看了一天了只是有了思路,还是写不出来。。。又看来了别人的代码。。。
标签:
原文地址:http://www.cnblogs.com/ttmj865/p/4703071.html