First, two concepts are identified:
In reverse order: series A[1],a[2],a[3] ... Any two numbers in A[i],a[j] (i<j), if A[I]>A[J], then we say that these two numbers constitute an inverse pair.
Number of reverse order: The total number of reverse pairs in a series.
Example one: POJ 1804. Click to open link
Solution thinking: Each Exchange can only reduce one reverse order, and must be able to reduce a reverse order, so that the problem is converted to reverse order number . the size of the data is small, and violence can be excessive.
I have provided here a method of merge_sort to solve the reverse order number, the time complexity is O (NLOGN).
about Merge Sort: The merge sort is to divide the series A[l,h] into two halves a[l,mid] and a[mid+1,r], respectively, and then combine the two halves together.
In the process of merging (set L<=i<=mid,mid+1<=j<=r), when A[i]<=a[j], the number of reverse order is not generated; when A[i]>a[j], the first half a[i] larger than a[j], will a[j] in front of a[i], reverse order number to add mid+1-i. Therefore, The number of reverse orders can be counted in the merging process in the merge order .
#include <cstdio> #define N 1000+10int ans=0;int f[n],t[n];void merge (int l,int m,int R)//around two tables merged into one table {int i=l,j=m +1,cnt=0; while (i<=m && j<=r) {if (F[i]<=f[j]) t[cnt++]=f[i++]; else {ans+=m-i+1; T[cnt++]=f[j++]; The core code that solves the number of reverse order. }} while (I<=m)//Joso table is not empty t[cnt++]=f[i++]; while (J<=R)//If the right table is not empty t[cnt++]=f[j++]; for (int k=0;k<cnt;)//Modify original array f[l++]=t[k++];} void Merge_sort (int l,int R)//merge sort {if (l==r) return; else {int m= (L+R) >>1; Merge_sort (L,M); Merge_sort (M+1,R); Merge (L,M,R); }}int Main () {int t,cas=0; scanf ("%d", &t); while (t--) {int n; scanf ("%d", &n); for (int i=0;i<n;i++) scanf ("%d", &f[i]); ans=0; Merge_sort (0,n-1); printf ("Scenario #%d:\n%d\n\n", ++cas,ans); } return 0;}
Example 2:poj 2299. Click to open link
There is no difference, but n larger, O (n^2) algorithm must be timed out, it is necessary to use Merge_sort, but also note to use a long long.
#include <cstdio> #define N 500000+10long long ans=0;int f[n],t[n];void Merge (int l,int m,int r) { int i=l,j=m+1, cnt=0; while (i<=m && j<=r) { if (F[i]<=f[j]) t[cnt++]=f[i++]; else { ans+=m-i+1; T[cnt++]=f[j++]; } } while (i<=m) t[cnt++]=f[i++]; while (j<=r) t[cnt++]=f[j++]; for (int k=0;k<cnt;) f[l++]=t[k++];} void Merge_sort (int l,int r) { if (l==r) return; else { int m= (l+r) >>1; Merge_sort (l,m); Merge_sort (m+1,r); Merge (l,m,r);} } int Main () { int n; while (scanf ("%d", &n), N) {for (int i=0;i<n;i++) scanf ("%d", &f[i]); ans=0; Merge_sort (0,n-1); printf ("%lld\n", ans); } return 0;}
Example 3:hdu 4911. Click to open link
Here the topic set another condition, can only exchange k times, so, first use Merge_sort to find out ans, then compare with K (Ans<=k->0; Ans>k, Ans-k;).
#include < Cstdio> #define N 500000+10long long ans=0;int f[n],t[n];void Merge (int l,int m,int r) {int i=l,j=m+1,cnt=0; while (i<=m && j<=r) {if (F[i]<=f[j]) t[cnt++]=f[i++]; else {ans+=m-i+1; T[cnt++]=f[j++]; }} while (I<=m) t[cnt++]=f[i++]; while (J<=R) t[cnt++]=f[j++]; for (int k=0;k<cnt;) f[l++]=t[k++];} void Merge_sort (int l,int r) {if (l==r) return; else {int m= (L+R) >>1; Merge_sort (L,M); Merge_sort (M+1,R); Merge (L,M,R); }}int Main () {int n,k; while (scanf ("%d%d", &n,&k) ==2) {for (int i=0;i<n;i++) scanf ("%d", &f[i]); ans=0; Merge_sort (0,n-1); if (ans>k) printf ("%lld\n", ans-k); else printf ("0\n"); } return 0;}
Merge sort to find the reverse number (POJ 1804,poj 2299,hdu 4911)