時間限制: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
- 當A[i] < mx時,值爲(A[i],mx)的奇數個數有cnt=(mx-A[i])/2,這些數要麼全部放在mx前面,要麼全部放在A[i]的後面,逆序貢獻總是cnt(放在中間的話逆序貢獻爲2*cnt),我們選擇放在A[i]的後面。
- 當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;
}