HDU 1394 Minimum Inversion Number (tree array), hduinversion
Question Link: Http://acm.hdu.edu.cn/showproblem.php? Pid = 1, 1394
Analysis:
First, this is the problem of solving the reverse order number. First, we need to know what the reverse order number is?
In an arrangement, if the front and back positions of a pair of numbers are in the opposite order of size, that is, the front number is greater than the back number, they are called a reverse order. The total number of reverse orders in an arrangement is called the number of reverse orders in this arrangement.
The reverse logarithm naturally comes to mind with a tree array, which is convenient and fast.
According to the meaning of the question, the arrangement is to move the first element to the final arrangement, so we can start from here,
For the first element, if it is smaller than it, it will certainly form a reverse order. In this way, when the first element is moved to the end of the current reverse order, its reverse logarithm reduces the value of this element and then minus one. Because the value of this question is continuous, it can be directly reduced, the number greater than the value of this element and it will form a reverse order. In this way, after the previous value is reduced, we need to add the total number of elements minus the value of this element. In this way, the obtained value is the reverse logarithm of the new arrangement. For example, if we want to move a [0] to the end, the total number of elements is n, and the current reverse logarithm is sum, then when we move a [0] to the end, sum + = N-a [0]-1-a [0].
With this method, we can calculate the smallest reverse logarithm of all sorts in O (n) time. The total time complexity is O (nlogn ).
Code:
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>#include <vector>using namespace std;const int MAXN=5005;#define Lowbit(x) ((x)&(-(x)))int a[MAXN], c[MAXN];int N;void ADD(int p, int val){ while(p>0){ c[p]+=val; p-=Lowbit(p); }}int getsum(int p){ int sum = 0; p++; while(p<=N){ sum += c[p]; p+=Lowbit(p); } return sum;}int main(){ while(~scanf("%d", &N)){ int i,x; int sum = 0; memset(c, 0, sizeof(c)); for(i=0; i<N; ++i){ scanf("%d", &a[i]); sum += getsum(a[i]+1); ADD(a[i]+1, 1); //printf("%d\n", sum); } int ans = sum; for(i=0; i<N; ++i){ sum+=(N-1-2*a[i]); ans = min(ans, sum); } printf("%d\n", ans); } return 0;}
Hdu 1394 has timed out. The eldest brother can help me optimize it.
No need to perform Merge-sort N times
After one operation, you can use Linear Scan. The key is to calculate the Inversion Pair quantity change rule after no number is moved.
# Include <iostream>
Using namespace std;
Void mergestor (int r, int l );
Void merge (int r, int m, int l );
Int a [100000];
Int t [100000];
Int s [100000];
Int q [100000];
Int o;
Int main ()
{
Int n;
While (scanf ("% d", & n )! = EOF)
{
O = 0;
Int I;
For (I = 0; I <n; I ++)
{
Scanf ("% d", & q [I]);
A [I] = q [I];
}
Int j;
Int w;
Int min;
Min = 10000000;
/*************************************** **/
O = 0;
Mergestor (0, n-1 );
S [0] = o;
Min = o;
For (j = 0; j <n; j ++)
{
S [j + 1] = s [j]-q [j] * 2 + n-1;
If (s [j + 1] <min) min = s [j + 1];
}
Printf ("% d \ n", min );
}
Return 0;
}
Void mergestor (int r, int l)
{
If (r <l)
{
Int mid;
Mid = (l + r)/2;
Mergestor (r, mid );
Mergestor (mid + 1, l );
Merge (r, mid, l );
}
}
Void merge (int r, int m, int l)
{
Int I, j, k;
I = r;
J = m + 1;
K = 0;
While (I <= m & j <= l)
{
If (a [I] <= a [j])
{
T [k] = a [I];
K ++;
I ++;
}
Else
{
T [k] = a [j];
K ++;
J ++;
O = o + m-I + 1;
}
}
While (I <= m)
{
T [k] = a [I];
K ++;
I ++;
}
While (j <= l)
{
T [k] = a [j];
K ++;
J ++;
}
For (I = 0; I <= (l-r); I ++)
{
A [r + I] = t [I];
}
}... Remaining full text>