http://acm.hdu.edu.cn/showproblem.php?pid=1394Minimum Inversion number
problem DescriptionThe inversion number of a given number sequence A1, A2, ..., is 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 Would obtain 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.
InputThe 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.
Outputfor each case, output the minimum inversion number in a single line.
Sample Input101 3 6 9 0 8 5 7 4 2
Sample Output -
1#include <cstdio>2#include <cstring>3#include <algorithm>4 using namespacestd;5 #defineN 50056 #defineLson rt<<1,l,m7 #defineRson Rt<<1|1,m+1,r8 structnode9 {Ten intL,r,value; One}tree[n<<2]; A intA[n]; - /* - the minimum number of reverse order after displacement the Update single point increase or decrease - Query Interval summation - */ - voidBuild (intRtintLintR) + { -Tree[rt].l=l; +Tree[rt].r=R; ATree[rt].value=0; at if(L==R)return ; - intM= (l+r) >>1; -Build (rt<<1, l,m); -Build (rt<<1|1, m+1, R); - } - in voidUpdate (intRtintnum) - { to if(tree[rt].l==num&&tree[rt].r==num) { +Tree[rt].value=1; - return ; the } * intM= (TREE[RT].L+TREE[RT].R) >>1; $ if(num<=m) Update (rt<<1, num);Panax Notoginseng ElseUpdate (rt<<1|1, num); -tree[rt].value=tree[rt<<1].value+tree[rt<<1|1].value; the } + A intQuery (intRtintLintR) the { + /* - draw a picture to understand that the search interval for [l,r],m represents the current node of the left son and the right son's branch $ If the left son has an element that contains the interval, that is, l<=m, then he will continue to search the left son recursively . $ If the right son has elements that contain the interval, that is, m<r, then continue to search for the right son recursively . - When the interval of the current node is covered by the search interval [l,r], it means that the interval is completely within [L,r] - then return the value of the node the */ - if(l<=tree[rt].l&&tree[rt].r<=R) {Wuyi returnTree[rt].value; the } - Else{ Wu intM= (TREE[RT].L+TREE[RT].R) >>1; - ints1=0, s2=0; About if(l<=m) S1=query (rt<<1, l,r); $ if(r>m) S2=query (rt<<1|1, l,r); - returns1+S2; - } - } A + intMain () the { - intN; $ while(~SCANF ("%d",&N)) { theBuild (1,1, n); the intsum=0; the for(intI=0; i<n;i++){ thescanf"%d",&a[i]); -a[i]++; inSum+=query (1, a[i]+1, n); theUpdate (1, A[i]); the } About intres =sum; the for(inti=n-1; i>=0; i--){ thesum=sum-(N-a[i]) + (a[i]-1); the if(sum<res) res=sum; + } -printf"%d\n", res); the }Bayi return 0; the}
HDU 1394:minimum Inversion Number (segment tree interval summation single point update)