题解:AT_abc470_d [ABC470D] Inverse and Swap
注意到,几乎所有题目都可以通过若干个“注意到”来解决,本题更是如此。
1. 题目思路
注意到,排列
注意到,本题暴力复杂度过高。我们先考虑没有操作
我们来考虑操作
注意到,此时对于操作
注意到,此时对于操作 true 和 false 互换)。操作
我们利用了五个“注意到”完美解决了本题。
2. 代码
注:代码仅供参考。
#include<bits/stdc++.h>
using namespace std;
const int max_n=5e5+2;
int n,q,p[max_n],op,x,y;
int z[max_n];
bool printp; //是否输出原数组
int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-48;
ch=getchar();
}
return x*f;
}
int main(){
n=read(),q=read();
for(int i=1;i<=n;i++){
p[i]=read();
z[p[i]]=i;
}
printp=true;
for(int i=1;i<=q;i++){
op=read();
if(op==1){
x=read(),y=read();
if(printp){
z[p[x]]=y,z[p[y]]=x;
swap(p[x],p[y]);
}
else{
p[z[x]]=y,p[z[y]]=x;
swap(z[x],z[y]);
}
}
else{
printp=!printp; //取反
}
}
if(printp){
for(int i=1;i<=n;i++){
printf("%d ",p[i]);
}
puts("");
}
else{
for(int i=1;i<=n;i++){
printf("%d ",z[i]);
}
puts("");
}
return 0;
}