NYOJ 117 求逆序数 (归并排序)

地址:http://acm.nyist.net/JudgeOnline/problem.php?pid=117

思路:归并排序,表示不太懂。。。。

算法分析:这个题的算法是利用归并排序的 merge() 函数,在处理在处理两段时,恰好要比较大小,顺便把逆数也求出来 故时间复杂度o(nlogn);

 1 #include<stdio.h>

 2 #include<stdlib.h>

 3 #define N 1000010

 4 long long ans;

 5 int a[N];

 6 void merge(int s1,int e1,int s2,int e2)

 7 {

 8     int p1,p2,p;

 9     int* temp = new int[e2-s1+5];  //归并为有序的temp ,此处定义temp 

10     p=0;p1=s1;p2=s2;

11     while(p1<=e1&&p2<=e2)   //将s1到e1和s2到e2合并到temp 

12     {

13         if(a[p1]<=a[p2])

14         {

15             temp[p++]=a[p1++];

16             continue;

17         }

18         else 

19         {

20             temp[p++]=a[p2++];

21             ans+=e1-p1+1;   //关键所在

22             continue;

23         }

24     }

25     while(p1<=e1) temp[p++]=a[p1++];  //将剩余的复制到temp 

26     while(p2<=e2) temp[p++]=a[p2++];

27     int i;

28     for(i=s1;i<=e2;i++) a[i]=temp[i-s1];

29     delete temp;

30 }

31 

32 void merge_sort(int s,int e)

33 {

34     int m;

35     if(s<e)

36     {

37         m=(s+e)/2;

38         merge_sort(s,m);

39         merge_sort(m+1,e);

40         merge(s,m,m+1,e);

41     }

42 }

43 

44 int main()

45 {

46     int test;

47     scanf("%d",&test);

48     while(test--)

49     {

50         int n,i;

51         ans=0;

52         scanf("%d",&n);

53         for(i=0;i<n;i++)

54             scanf("%d",&a[i]);

55         merge_sort(0,n-1);

56         printf("%lld\n",ans);

57     }

58 }

用归并排序求逆序数。归并排序中适当的位置加上cnt+=n1-i,就可以了。

 

 

你可能感兴趣的:(归并排序)