Nowcoder-2018ACM多校訓練營(第五場)D inv

時間限制:C/C++ 2秒,其他語言4秒
空間限制:C/C++ 262144K,其他語言524288K
64bit IO Format: %lld

題目描述 

Kanade has an even number n and a permutation b of all of the even numbers in [1,n]

Let a denote an array [1,3,5....n-1] , now you need to find a permutation of [1,n] satisfy both a and b are subsequence of it and minimize the number of inverse pair of it.

 

輸入描述:

The first line has a positive even integer n

The second line has n/2 positive even integers b[i]

輸出描述:

Output the number of inverse pair of the permutation you find.

示例1

輸入

複製

6
2 6 4

輸出

複製

2

說明

[1,2,3,5,6,4]

備註:

1≤ n≤ 2*105

題解:由於奇數序列是遞增的,考慮將奇數序列插入偶數系列中。設偶數序列中當前遍歷到A[i],假設前i-1項中最大的爲mx

  1. 當A[i] < mx時,值爲(A[i],mx)的奇數個數有cnt=(mx-A[i])/2,這些數要麼全部放在mx前面,要麼全部放在A[i]的後面,逆序貢獻總是cnt(放在中間的話逆序貢獻爲2*cnt),我們選擇放在A[i]的後面。
  2. 當A[i] >= mx時,原本放在mx後面的且大於A[i]的奇數,可以選擇放在A[i]的後面,此時沒有貢獻。

對於偶數序列之間的逆序,用歸併或者樹狀數組求一下即可。

#include <bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define x first
#define y second
#define rep(i,a,b) for(int i=a;i<b;++i)
#define per(i,a,b) for(int i=a-1;i>=b;--i)
#define fuck(x) cout<<'['<<#x<<' '<<(x)<<']'
#define FIN freopen("in.txt","r",stdin);
using namespace std;
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;

const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fll;
const int mod = 1e9 + 7;
const int MX = 2e5 + 5;

ll pow(ll a, int b) {
    ll ret = 1;
    while(b) {if(b & 1) ret = ret * a % mod; a = a * a % mod; b >>= 1;}
    return ret;
}
inline ll mul(ll a, ll b, ll c) {return a * b % mod * c % mod;}

int b[MX], c[MX];
ll ans;
void solve(int l, int r) {
    if(r - l <= 1) return;
    int m = (l + r) >> 1, p1 = l, p2 = m;
    solve(l, m), solve(m, r);
    rep(i, l, r) {
        if(p2 >= r || (p1 < m && b[p1] < b[p2])) c[i] = b[p1++];
        else c[i] = b[p2++], ans += m - p1;
    }
    rep(i, l, r) b[i] = c[i];
}
int main() {
    //FIN;
    int n; cin >> n;
    rep(i, 0, n / 2) scanf("%d", &b[i]);
    priority_queue<int>q;
    rep(i, 0, n / 2) {
        int x = b[i] / 2;
        q.push(x);
        if(q.top() > x) {
            ans += q.top() - x;
            fuck(b[i]),fuck(q.top()-x),puts("");
            q.pop();
            q.push(x);
        }
    }
    solve(0, n / 2);
    cout << ans << endl;
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章