逆序对(归并排序) 易错点(两个递增变量的使用)

用归并排序:

计算左部分的任意一个数 比 右部分的数大的数目, ("任意"用递增实现,i每加1,计算一次)

则要求

左部分的数(b[i])要一直比右部分的数(b[j])大,

所以当b[i]=b[j]时,i递增

 

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <time.h>
 6 #include <string>
 7 #include <set>
 8 #include <map>
 9 #include <list>
10 #include <stack>
11 #include <queue>
12 #include <vector>
13 #include <bitset>
14 #include <ext/rope>
15 #include <algorithm>
16 #include <iostream>
17 using namespace std;
18 #define ll long long
19 #define minv 1e-6
20 #define inf 1e9
21 #define pi 3.1415926536
22 #define E  2.7182818284
23 const ll mod=1e9+7;//998244353
24 const int maxn=1e5+10;
25 
26 int a[maxn],b[maxn];
27 ll g=0;
28 
29 void mergesort(int l,int r)
30 {
31     if (l==r)
32         return ;
33     int m=(l+r)>>1,i,j,k;
34     mergesort(l,m);
35     mergesort(m+1,r);
36     for (i=l;i<=r;i++)
37         b[i]=a[i];
38     i=l; j=m+1; k=l;
39     while (i<=m && j<=r)
40     {
41         if (b[i]<=b[j])
42         {
43             a[k++]=b[i++];
44             g+=(j-m-1);//[m+1,j)
45         }
46         else
47             a[k++]=b[j++];
48     }
49     if (i<=m)
50         g+=1ll*(j-m-1)*(m+1-i);
51     while (i<=m)
52         a[k++]=b[i++];
53     while (j<=r)
54         a[k++]=b[j++];
55 }
56 
57 int main()
58 {
59     int n,i;
60     scanf("%d",&n);
61     for (i=1;i<=n;i++)
62         scanf("%d",&a[i]);
63     mergesort(1,n);
64     printf("%lld",g);
65 }
66 /*
67 3
68 1 2 3
69 
70 3
71 1 3 2
72 
73 5
74 5 4 3 2 1
75 
76 5
77 5 1 4 3 2
78 */

 

posted @ 2018-08-22 11:27  congmingyige  阅读(231)  评论(0编辑  收藏  举报