cqyz oj | Fenwick tree | cycle to reverse | reverse order

  • 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 000
A 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.
 
The title says the next sequence is the first element of a sequence of these last mentioned made,
Easy to find these two sequences have to reverse much of the same, only to have to reverse the change on that element of the changes.
Each time a [1] into Finally, the entire sequence of the reverse increases b - l pair,
Wherein b is [1] a large number of elements than the back, i.e. reverse to the new number,
l is the ratio of the number of back a [1] of the light elements, i.e., to reduce the number of reverse
And b l can be determined in O (1) time of the next transfer sequence
 
Fenwick tree can be used to obtain a [i] of the left and right, respectively, than the number of elements a [i] Small (l [i], r [i]),
Then a [i] on the left than it is to a large number of dl [i] = i-1-l [i], the right side is larger than the number of which dr [i] = nir [i]
 
A a [1] are sequentially calculated after each element of the last-mentioned sequence number of reverse ans
则b = dl[i] + dr[i],l = l[i] +r[i]
Transfer: ans = ans + (b - l)
  = ans + (dl[i] + dr[i] - l[i] - r[i])
  Ans = + ((i-1 L [i]) + (NIR [i]) - l [in] - r [i])
  = Years + (n - 1 - 2 * (l [i] + r [i]))
 
An initial state need to be calculated: ans1 = sum (r [i]) or sum (i-1-l [i])
The answer can take ans minimum
 
#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;
}

 

Guess you like

Origin www.cnblogs.com/de-compass/p/11426247.html