Still practicing the use of the tree array:
The main topic: give the number of n, these numbers can be deleted from the back and then put to the front to form a new sequence
Can be obtained in the N case, find out in these n cases which kind of the number of reverse order of the smallest
problem-solving ideas: first to find the first sequence of the reverse number, and then use a very clever way to find the next sequence of the number of reverse, until all to find out
Sequence 4 5 2 1 3 6, this sequence has an inverse number of 7, it waits for the next sequence of 5 2 1 3 6 4
Look at this new sequence of the production process, the first delete 4, the tail add 4
Deleting 4 will inevitably reduce the number of reverse-order numbers (4-1) for this sequence, since 4 must have 4-1 numbers less than 4
Adding 4 will inevitably increase the number of reverse-order numbers (6-4) for this sequence, since 4 must have 6-4 numbers greater than 4
The formula is introduced, assuming that the number of moves is M, the number of reverse order of the sequence = previous sequence number-(m-1) + (N-M)
The first thing to be discretized (that doesn't seem to be necessary, but I'm still discrete), because the data range is 0~n-1
<pre name= "code" class= "CPP" >//tree-like array #include<iostream> #include <algorithm> #include <string.h >using namespace Std;int N; #define MAX 5010typedef struct nano{ int val; int order;} Node;node a[max];int aa[max];int C[max];int cmp (node A,node b) { return a.val<b.val;} void update (int x) { while (x<=n) { c[x]++; x+= (x&- x); }}int sum (int x) { int s=0; while (x>=1)//Must be 1!0 dead loop { &NB Sp s+=c[x]; x-= (x&-x); } return s;} int main (int argc, char *argv[]) { //freopen ("1394.in", "R", stdin); while (scanf ("%d", &n)! = EOF) { for (int i=1;i<=n;++i) { & nbsp scanf ("%d", &a[i].val); &NBSP; a[i].order=i; } /*for (int i=1;i<=n;++i) &NBSP ; printf ("%d", A[i].val);*/ sort (a+1,a+n+1,cmp); //printf ("\ n "); for (int i=1;i<=n;++i) aa[a[i].order]=i; & nbsp Long long ans=0; /* printf ("------\ n"); for (int i=1;i& Lt;=n;++i) { printf ("%d", Aa[i]); }*/ //printf ("\ n------\ n"); memset (c,0,sizeof ( c); for (int i=1;i<=n;++i) { update (aa[i]); &N Bsp ans+= (I-sum (aa[i)); } Long Long Min=ans ; &nbsP for (int i=1;i<=n;++i) { ans=ans-(aa[i]-1) + (N-aa[i]); & nbsp if (ans<min) min=ans; } printf ("%lld\n" , MIN); } return 0;}
As for the speed, with the previous merge sort solution time-consuming, perhaps the data is small, no difference, but in the data range is very large, the use of discretization is very useful, after all, limited to memory limits, can not open so large data space.
HDU 1394 Minimum Inversion number (tree-like array)