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;
}

猜你喜欢

转载自www.cnblogs.com/JYYHH/p/9270142.html