思路很巧妙啊
code:
#include <cstdio> #include <cstring> #include <algorithm> #define ll long long #define N 1000009 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int n,m,cnt; int S[N],b[N],X[N],Y[N],nxt[N],lst[N],pos[N]; int check(int u) { int i,j; for(i=1;i<=n;++i) b[i]=S[i]; for(i=1;i<=u;++i) swap(b[X[i]],b[Y[i]]); int sum=0; for(i=1;i<=n;++i) nxt[b[i]]=i; for(i=1;i<=n;++i) { while(nxt[i]!=i) ++sum,swap(nxt[i],nxt[nxt[i]]); } return sum<=u; } void solve(int u) { if(u==0) return; int i,j; for(i=1;i<=n;++i) b[i]=lst[i]=S[i],pos[b[i]]=i; // lst[i] 表示最终位置 i 的数字. for(i=1;i<=u;++i) swap(lst[X[i]],lst[Y[i]]); for(i=1;i<=n;++i) nxt[lst[i]]=i; int nw=1; while(nxt[nw]==nw) ++nw; for(i=1;i<=u;++i) { swap(b[X[i]],b[Y[i]]); swap(pos[b[X[i]]],pos[b[Y[i]]]); if(nw<=n) { int u=pos[nw],v=pos[nxt[nw]],temp=nxt[nxt[nw]]; printf("%d %d ",u-1,v-1); swap(b[u],b[v]); swap(pos[nw],pos[nxt[nw]]); swap(nxt[nw],nxt[nxt[nw]]); ++cnt; while(nxt[nw]==nw) ++nw; } } if(cnt<u) for(i=cnt+1;i<=u;++i) printf("0 0 "); } int main() { // setIO("input"); int i,j; scanf("%d",&n); for(i=1;i<=n;++i) { scanf("%d",&S[i]),++S[i]; b[i]=S[i]; } scanf("%d",&m); for(i=1;i<=m;++i) scanf("%d%d",&X[i],&Y[i]),++X[i],++Y[i]; int l=0,r=m,ans=0; while(l<=r) { int mid=(l+r)>>1; if(check(mid)) ans=mid,r=mid-1; else l=mid+1; } printf("%d ",ans),solve(ans); return 0; }