题解
任意交换两个数,会使序列的逆序对数加减一个奇数。(不懂的,请打开线性代数紫本第七版第五页)
所以如果两个序列,初始逆序对数的奇偶性不同,肯定无法兑换成功
那么,如果两个序列,初始逆序对数的奇偶性相同,是否一定能对换成功?
答案是一定可以的,我们做相邻对换,由于相邻对换总是可以操控逆序对数是加一还是减一,所以两个序列一定能对换到逆序对数相同的状态
code
#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x) & (-x))
int n;
struct node {
int v, id;
} a[100005], b[100005], c[100005], d[100005];
bool cmp(node x, node y) {
return x.v < y.v;
}
int tree[100005] = {0}, index[100005];
int query(int now) {
int res = 0;
while (now) {
res += tree[now];
now -= lowbit(now);
}
return res;
}
void update(int now) {
while (now <= n) {
tree[now]++;
now += lowbit(now);
}
}
void solve() {
cin >> n;
for (int i = 1; i <= n; i++) tree[i] = index[i] = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i].v;
a[i].id = i;
c[i] = a[i];
}
for (int i = 1; i <= n; i++) {
cin >> b[i].v;
b[i].id = i;
d[i] = b[i];
}
sort(c + 1, c + 1 + n, cmp);
sort(d + 1, d + 1 + n, cmp);
for (int i = 1; i <= n; i++) {
if (c[i].v != d[i].v) {
puts("no");
return;
}
index[d[i].id] = c[i].id;
}
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += query(n) - query(index[i]);
update(index[i]);
}
//printf("sum: %d\n", sum);
if (sum % 2) puts("no");
else puts("yes");
}
int main() {
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
标签:Dilemma,int,对换,100005,Swap,对数,now,逆序
From: https://www.cnblogs.com/pure4knowledge/p/18292578