1. 程式人生 > 實用技巧 >arc 043 c 題解

arc 043 c 題解

arc 043 c

若我們另外弄兩個陣列\(a'\)\(b'\),其中\(a'[i]\)表示i在\(a\)中的位置,\(b'[i]\)表示i在b中的位置。

則転倒距離就是有多少對\((i,j)\)滿足\((i<j)\)\(a'[i],a'[j]\)\(b'[i]\)\(b'[j]\)大小關係不一樣。這樣就可以發現有解的充要條件就是\(A,B\)的転倒距離是偶數

首先求転倒距離的方法比較簡單就是在A裡從前往後掃一遍,在B裡標記位置。用bit就可以了。

構造方法,我們在B中從前往後掃。若前面存在一些數在A中應該出現在當前數後面的數。若將這個移到前面去仍然小於等於應該交換的次數,就直接移動到這些數的前面。否則就移到一部分數的前面。

這樣,我們只需要對於一個數組,執行一系列操作: 將一個數向前移動x位。

我們可以對於第i個數記錄一個rank[i]表示第i個數在前i個的排名,從後往前還原即可。

sugim48

using namespace std;
 
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;
typedef pair<ll, int> ll_i;
typedef pair<double, int> d_i;
typedef pair<ll, ll> ll_ll;
typedef pair<double, double> d_d;
struct edge { int u, v; ll w; };
 
ll MOD = 1000000007;
ll _MOD = 1000000009;
double EPS = 1e-10;
 
struct bit {
	vector<ll> v;
	bit(int n) : v(n + 1) {}
	ll sum(int i) {
		ll res = 0;
		for (; i > 0; i -= i & -i) res += v[i];
		return res;
	}
	void add(int i, ll x) {
		for (i++; i < v.size(); i += i & -i) v[i] += x;
	}
};
 
int main() {
	int N; cin >> N;
	vector<int> A(N);
	for (int i = 0; i < N; i++) {
		cin >> A[i];
		A[i]--;
	}
	vector<int> B(N);
	for (int i = 0; i < N; i++) {
		cin >> B[i];
		B[i]--;
	}
	vector<int> a(N);
	for (int i = 0; i < N; i++)
		a[A[i]] = i;
	for (int i = 0; i < N; i++)
		B[i] = a[B[i]];
	vector<int> hoge(N);
	for (int i = 0; i < N; i++)
		hoge[B[i]] = i;
	ll inv = 0;
	bit b(N);
	vector<int> unko(N);
	for (int i = 0; i < N; i++) {
		inv += i - b.sum(hoge[i]);
		unko[i] = i - b.sum(hoge[i]);
		b.add(hoge[i], 1);
	}
	if (inv % 2 == 1) {
		cout << -1 << endl;
		return 0;
	}
	inv /= 2;
	vector<int> ans(N);
	bit c(N);
	for (int i = N - 1; i >= 0; i--) {
		int k = min(inv, (ll)unko[i]);
		inv -= k;
		int t = i - unko[i] + k;
		int lb = 0, ub = N;
		while (ub - lb > 1) {
			int mid = (lb + ub) / 2;
			int x = mid - c.sum(mid);
			if (x <= t) lb = mid;
			else ub = mid;
		}
		c.add(lb, 1);
		ans[lb] = i;
	}
	for (int i = 0; i < N; i++)
		B[i] = A[ans[i]];
	for (int i = 0; i < N; i++)
		cout << B[i] + 1 << (i + 1 < N ? ' ' : '\n');
}