CodeForces - 612E Square Root of Permutation
可以发现一个置换平方之后,奇环大小不变,偶环分裂成两个一样长的环,于是我们就可以把 p^2 中的奇环还原成原来的奇环,偶环合并即可。。
当一种长度的偶环有奇数个的时候无解。。。
#include<bits/stdc++.h> #define ll long long using namespace std; #define pb push_back const int N=1e6+5; inline int read(){ int x=0; char ch=getchar(); for(;!isdigit(ch);ch=getchar()); for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x; } void W(int x){ if(x>=10) W(x/10); putchar(x%10+'0');} vector<int> g[N]; int n,a[N],ans[N],p[N],len; bool v[N]; inline void work(int x){ for(len=0;!v[x];x=a[x]) p[++len]=x,v[x]=1; if(len==1) ans[x]=x; else if(len&1) for(int i=1,to=p[(len>>1)+2];i<=len;i++,to=a[to]) ans[p[i]]=to; else if(g[len].size()){ for(int i=1;i<len;i++){ ans[g[len][i-1]]=p[i]; ans[p[i]]=g[len][i]; } ans[g[len][len-1]]=p[len],ans[p[len]]=g[len][0]; g[len].clear(); } else for(int i=1;i<=len;i++) g[len].pb(p[i]); } int main(){ n=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<=n;i++) if(!v[i]) work(i); for(int i=1;i<=n;i++) if(!ans[i]){ puts("-1"); return 0;} for(int i=1;i<=n;i++) W(ans[i]),putchar(' '); return 0; }
我爱学习,学习使我快乐