题目大意
D - Inverse and Swap
时间限制:2 秒 / 内存限制:1024 MiB
分值:400 分
给定一个 (1,…,N) 的排列 P=(P1,…,PN)。
请依次处理 Q 个询问,询问有以下两种:
-
1 x y:交换 Px 与 Py 的值。
-
2:构造满足以下条件的 (1,…,N) 的排列 P′=(P1′,…,PN′),并将 P1,…,PN 的值分别替换为 P1′,…,PN′。(可以证明满足条件的 P′ 唯一存在。)
- 对每个满足 1≤i≤N 的整数 i,都有 PPi′=i。
请输出处理完所有询问后 P1,…,PN 的值。
输入从标准输入给出,格式如下:
1 2 3 4 5
| N Q P_1 P_2 ⋯ P_N query_1 ⋮ query_Q
|
其中 queryq 表示第 q 个询问,以下面两种格式之一给出:
将处理完所有询问后 P1,…,PN 的值以空格分隔,输出在一行中。
-
2≤N≤5×105
-
1≤Q≤5×105
-
(P1,…,PN) 是 (1,…,N) 的排列
-
对于类型 1 的询问,1≤x<y≤N
-
输入中的所有值均为整数
输入
1 2 3 4 5 6 7
| 5 5 2 1 3 5 4 1 2 4 2 1 2 3 1 3 4 2
|
输出
说明
每个询问处理完成时,P1,…,PN 的值如下:
-
处理完第 1 个询问时,P=(2,5,3,1,4)
-
处理完第 2 个询问时,P=(4,1,3,5,2)
-
处理完第 3 个询问时,P=(4,3,1,5,2)
-
处理完第 4 个询问时,P=(4,3,5,1,2)
-
处理完第 5 个询问时,P=(4,5,2,1,3)
输入
1 2 3 4 5 6
| 7 4 3 7 5 6 4 2 1 2 2 2 2
|
输出
说明
本样例中的 4 个询问均为类型 2,处理完成后 P 与初始时相同。
输入
1 2 3 4 5 6 7 8 9 10
| 10 8 7 3 2 4 8 5 10 9 1 6 2 1 4 10 1 6 9 2 1 9 10 1 3 10 2 1 4 6
|
输出
说明
本样例包含两种询问混合出现的情况,请按照询问给出的顺序依次处理。
思路讲解

那么实际上,排列就是位置和值的对应关系啊,至于箭头的方向和哪边是位置,哪边是值,这个其实不是特别重要啊,用一个变量 f 维护一下即可啊。
那么这个叫什么交换操作就只是需要修改一下这个对应关系即可啊,这个就非常简单,你可以理解为我们就是一个无向图啊,然后最后再进行定向即可啊。
当然,还是要注意一下值和位置当前的对应关系啊。
存储的时候,S 和 T都可以看成是一个只有一条出边的有向图邻接表啊,那么实际上,我们存储的就是这个无向图啊。因为无向图就是一条边有两个方向的有向图嘛。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| int mp[2][500005];
int main() { ios::sync_with_stdio(false); cin.tie(nullptr);
int n, q; cin >> n >> q;
for (int i = 1; i <= n; i++) { cin >> mp[0][i]; mp[1][mp[0][i]] = i; }
int f = 0;
while (q--) { int op; cin >> op;
if (op == 2) { f ^= 1; continue; }
int x, y; cin >> x >> y;
int *S = mp[f]; int *T = mp[f ^ 1];
int u = S[x], v = S[y];
tie(S[x], S[y], T[u], T[v]) = make_tuple(v, u, y, x); }
const int *R = mp[f]; for (int i = 1; i <= n; i++) cout << R[i] << " \n"[i == n];
return 0; }
|
AC代码
https://atcoder.jp/contests/abc470/submissions/78275932
AI 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| #include <bits/stdc++.h> using namespace std;
int mp[2][500005];
int main() { ios::sync_with_stdio(false); cin.tie(nullptr);
int n, q; cin >> n >> q;
for (int i = 1; i <= n; i++) { cin >> mp[0][i]; mp[1][mp[0][i]] = i; }
int f = 0;
while (q--) { int op; cin >> op;
if (op == 2) { f ^= 1; continue; }
int x, y; cin >> x >> y;
int *S = mp[f]; int *T = mp[f ^ 1];
int u = S[x], v = S[y];
tie(S[x], S[y], T[u], T[v]) = make_tuple(v, u, y, x); }
const int *R = mp[f]; for (int i = 1; i <= n; i++) cout << R[i] << " \n"[i == n];
return 0; }
|
心路历程(WA,TLE,MLE……)