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 }
View Code

 

posted @ 2015-03-09 23:09  xiaxiaosheng  阅读(487)  评论(0编辑  收藏  举报