HDU 3743 Frosh Week(归并排序求逆序对)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3743
题目意思就是给你一个长为n的序列,让你求逆序对.我用的是归并排序来求的.归并排序有一个合并的过程,分前后两段,当a[i] > a[j]时,说明a[j]比前面那段啊[i],a[i+1],a[i+2]....,a[mid],比这些都要小,所以总逆序对数要加上mid-i+1.
1 // File Name: HDU3743.cpp 2 // Author: xiaxiaosheng 3 // Created Time: 2015年03月09日 星期一 21时54分45秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 25 using namespace std; 26 typedef __int64 INT; 27 const int maxn = 10e6+10; 28 29 int n,A[maxn],temp[maxn]; 30 INT ans; 31 void merger(int *A,int s,int mid,int e) 32 { 33 int k = 0,i = s,j = mid+1; 34 while(i <= mid && j <= e) 35 { 36 if(A[i] < A[j]) 37 temp[k++] = A[i++]; 38 else 39 { 40 ans += (mid-i+1); 41 temp[k++] = A[j++]; 42 } 43 } 44 while(i <= mid) temp[k++] = A[i++]; 45 while(j <= e) temp[k++] = A[j++]; 46 for(int i = 0;i < k;++i) 47 A[s+i] = temp[i]; 48 } 49 void mergersort(int *A,int s,int e) 50 { 51 if(s < e) 52 { 53 int mid = (s + e) / 2; 54 mergersort(A,s,mid); 55 mergersort(A,mid+1,e); 56 merger(A,s,mid,e); 57 } 58 59 } 60 int main(){ 61 while(scanf("%d",&n)!=EOF) 62 { 63 for(int i = 0;i < n;++i) 64 scanf("%d",&A[i]); 65 ans = 0; 66 mergersort(A,0,n-1); 67 printf("%I64d\n",ans); 68 } 69 return 0; 70 }