逆序对(归并排序) 易错点(两个递增变量的使用)
用归并排序:
计算左部分的任意一个数 比 右部分的数大的数目, ("任意"用递增实现,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 */