[ABC279E] Cheating Amidakuji 题解

· · 题解

很妙的一道题,完美利用了交换操作的一些性质。

首先,不考虑忽略的操作——即假设全部操作都正常进行;对于每次操作,用 X_i 记录第 i 次操作的第一个数,Y_i 记录第 i 次操作的第二个数。

接着,利用 C_i 记录 B_i 最终的位置;

最后,我们来考虑忽略掉的操作——对于忽略第 i 个操作,如果本次操作对 1 有影响,那么 1 最终的位置其实就是不忽略操作时和它交换的数最终的位置(判断操作对 1 有没有影响,即为判断是否 X_i=1Y_i=1)。这样,直接调用 C 数组存下的答案即可求解。

放代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
  ios::sync_with_stdio(false);
  int n,m; cin>>n>>m;
  vector<int> x(m),y(m),a(m),b(n+1),c(n+1);
  iota(b.begin(),b.end(),0);
  for(int i=0;i<m;i++){
    cin>>a[i],x[i]=b[a[i]],y[i]=b[a[i]+1];
    swap(b[a[i]],b[a[i]+1]);
  } // 模拟正常操作
  for(int i=1;i<=n;i++)c[b[i]]=i; // 记录 c 数组
  for(int i=0;i<m;i++){
    if(x[i]==1)cout<<c[y[i]]<<'\n'; // 1 是第一个操作数
    else if(y[i]==1)cout<<c[x[i]]<<'\n'; // 1 是第二个操作数
    else cout<<c[1]<<'\n';
  }
  return 0;
}