专栏文章

题解:AT_abc399_d [ABC399D] Switch Seats

AT_abc399_d题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miprcy5z
此快照首次捕获于
2025/12/03 16:41
3 个月前
此快照最后确认于
2025/12/03 16:41
3 个月前
查看原文

题意

NN 组数字对(称为“情侣对”)排成一列。
请统计满足以下所有条件的 两对不同的情侣对 (a,b)(a, b) 的组数:
  1. 在原序列中,aa 的两个出现位置不邻接。
  2. 在原序列中,bb 的两个出现位置不邻接。
  3. 通过执行以下操作(次数不限),可以使 aa 的两个出现位置邻接,同时 bb 的两个出现位置也邻接:
    • 选择两个位置 (i,j)(i, j) 满足 Ai=aA_i = aAj=bA_j = b,并交换这两个位置的值。
给定一个长度为 2N2N 的序列 A=(A1,A2,,A2N)A = (A_1, A_2, \dots, A_{2N}),其中每个 1,2,,N1, 2, \dots, N 恰好出现两次。
对于 TT 个测试用例,分别输出答案。
我是天才。
好了,不整了。
下面是正片: 求存在多少个数对 (a,b)(a,b) 满足上述条件。
我是天才。

思路

对于每一个 ai(2i2n)a_i(2\le i \le 2n) ,判断:
  1. 是否在之前出现过
    • 使用数组记录最后一个数并判断
  2. 是否连续
  3. 前一个或后一个是否是下一次出现的前一个或后一个

代码

CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;

int a[1000010];
int lst[1000010];

void solve() {
    int n;
    cin >> n; 
    for (int i = 1; i <= 2 * n; i++) {
        cin >> a[i];
        lst[a[i]] = i;
    }
    a[2 * n + 1] = 0;
    int ans = 0;
    for (int i = 2; i <= 2 * n; i++) {
        if(lst[a[i]] <= i + 1) continue;
        if(a[lst[a[i]] + 1] == a[i + 1] || a[lst[a[i]] - 1] == a[i - 1]) ans ++;
    }
    cout << ans << "\n";
}

signed main() {
    int t = 1;
    cin >> t;
    while (t--) {
        solve();
    }
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...