D. Swap Dilemma

原题链接

题解

任意交换两个数,会使序列的逆序对数加减一个奇数。(不懂的,请打开线性代数紫本第七版第五页)
所以如果两个序列,初始逆序对数的奇偶性不同,肯定无法兑换成功
那么,如果两个序列,初始逆序对数的奇偶性相同,是否一定能对换成功?
答案是一定可以的,我们做相邻对换,由于相邻对换总是可以操控逆序对数是加一还是减一,所以两个序列一定能对换到逆序对数相同的状态

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;
}
posted @   纯粹的  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示