Problem Description
The inversion number of a given number sequence A1, A2, ..., the number of pairs (AI, AJ) that satisfy I < J and Ai > AJ.
For a given sequence of numbers a1, A2, ..., an, if we move the first m >= 0 numbers to the end of the seqence, we'll o Btain another sequence. There is totally n such sequences as the following:
A1, A2, ..., An-1, an (where m = 0-the initial seqence)
A2, A3, ..., an, A1 (where m = 1)
A3, A4, ..., an, A1, A2 (where m = 2)
...
An, A1, A2, ..., an-1 (where m = n-1)
You is asked to write a program to find the minimum inversion number out of the above sequences.
Input
The input consists of a number of test cases. Each case consists of the lines:the first line contains a positive integer n (n <= 5000); The next line contains a permutation of the n integers from 0 to n-1.
Output
For each case, output the minimum inversion number in a single line.
Sample Input
10
1 3 6 9 0 8 5 7 4 2
Sample Output
16
Thinking of solving problems
This problem has been a night of AC or too careless.
Because the data is small, it seems that violence can be too. It is certainly better to use a line tree.
The problem is divided into two steps
① not consider moving, use O (nlogn) to calculate the number of initial reverse order (assuming sum)
② the sum of the smallest case with the O (1) recursive sum using the mathematical formula
Look at the first step, with the line tree. each read into a number we consider only the number that has been read before it. we make it easy to count all the s[i]++ as positive integers of 1-n. Again, the distance between this number and N of the current read is already several numbers. They are the current number of "forward-looking reverse"
The second step. Assume that the current inverse pair is sum. Now consider the first number assumption that K puts it at the end of the queue. We know that in the 2nd to nth the number of k-1 is less than K, N-k is greater than K. So a move, natural reverse order on the number of less k-1, more n-k a. This keeps looping and constantly updating the minimum values.
Code
#include <cstdio>#include <cstring>#include <algorithm>using namespace STD;Const intMAXN =5010;intNintS[MAXN];intANS[MAXN];intsegtree[maxn<<2];voidUpdateintNodeintKintLintR) {if(l <= k && k <= R) Segtree[node] + +;if(L = = r)return;if(R < K | | L > K)return; Update (node<<1, K,l, (l+r)/2); Update ((node<<1)+1, K, (L+R)/2+1, r);}intQueryintAintBintNodeintLintR) {if(L > B | | r < a)return 0;if(A <= l && R <= B)returnSegtree[node];returnQuery (a,b,node<<1, L, (l+r)/2) +query (A, B, (node<<1)+1, (L+R)/2+1, r);}intMain () { while(scanf("%d", &n)! = EOF) {memset(S,0,sizeof(s));memset(ANS,0,sizeof(ans));memset(Segtree,0,sizeof(Segtree)); for(inti =1; I <= N; i + +) {scanf("%d", &s[i]); S[i] + +; Ans[i] = query (S[i],n,1,1, n); Update1, S[i],1, n); }intsum =0; for(inti =1; I <= N; i + +) sum + = Ans[i];intmi = sum; for(inti =1; I < n; i + +) {sum = sum+1+n-2*s[i];if(Sum < mi) mi = sum; }printf("%d\n", MI); }return 0;}
HDU1394 Minimum Inversion Number segment tree + Math