- Description
0 ~ n-1 sequence of numbers, and then such an operation, each time a top surface of the final element to get into a sequence, each sequence can be drawn to give a reverse of the sequence number (if one pair before and after the location and size of the number of reverse order, i.e., the number greater than the number in front of the latter, they are called a reverse. the reverse arrangement of a total number of the called number in reverse order). Requirements to obtain the smallest number in reverse order.
- Input
Comprising a plurality of input sets of data, each comprising two data lines, a first behavior integer n, is arranged in a second row of 0..n-1.
- Output
A data output line of each integer, representing the minimum number of reverse pair.
- Sample Input 1
10 1 3 6 9 0 8 5 7 4 2
- Sample Output 1
16
- Hint
n<=100 000A maximum of 10 sets of data.
One conventional approach is to reverse merge sort, but for this question, the n sequence n times merge sort, time to reach the O (n * n logn), timeout.
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<vector> #include<algorithm> #define maxn 100005 #define maxm 100005 #define lowbit(x) (x&(-x)) #define FOR(i,a,b) for(int i=(a);i<=(b);++i) #define ROF(i,a,b) for(int i=(a);i>=(b);--i) using namespace std; typedef long long ll; int n, a[maxn]; int c[maxm]; int l[maxn], r[maxn]; void add(int p){ while(p<=n) c[p]++, p += lowbit(p); } int query(int p){ int ans = 0; while(p) ans += c[p], p -= lowbit(p); return ans; } int main(){ while(scanf("%d",&n) == 1){ FOR(i, 1, n) scanf("%d",&a[i]), a[i]++; memset(c, 0, sizeof(c)); FOR(i, 1, n) l[i] = query(a[i]-1), add(a[i]); memset(c, 0, sizeof(c)); ROF(i, n, 1) r[i] = query(a[i]-1), add(a[i]); ll ans = 0, tmp; FOR(i, 1, n) ans += r[i]; tmp = ans; FOR(i, 1, n-1){ tmp += n - 1 - 2 * (l[i] + r[i]); ans = min(ans, tmp); } printf("%lld\n", ans); } return 0; }