[CF 612E]Square Root of Permutation
题目大意:
给你个置换p,然后做平方运算,得到置换q,题目给你q,问你能否找到p,要构造出来。
题解:
这道题要求倒推出一个置换,由于原置换p中的环不一定全是奇数环,所以平方之后有可能有环会裂开。
对于平方后的置换q中的奇数环,直接在里面推。偶数环就看是否有相同大小的偶数环与它合并。
1 //Never forget why you start 2 #include<iostream> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cmath> 7 #include<algorithm> 8 #include<vector> 9 using namespace std; 10 int n,m,a[1000005],lm,ans[1000005],q[1000005]; 11 struct node{ 12 int sum; 13 vector<int>p; 14 friend bool operator < (const node a,const node b){ 15 return a.sum<b.sum; 16 } 17 }s[1000005]; 18 int vis[1000005],cnt; 19 void dfs(int r){ 20 vis[r]=1; 21 cnt++; 22 s[lm].p.push_back(r); 23 if(vis[a[r]])return; 24 else dfs(a[r]); 25 } 26 int main(){ 27 int i,j; 28 scanf("%d",&n); 29 for(i=1;i<=n;i++)scanf("%d",&a[i]); 30 for(i=1;i<=n;i++) 31 if(!vis[i]){ 32 cnt=0; 33 lm++; 34 dfs(i); 35 s[lm].sum=cnt; 36 } 37 sort(s+1,s+lm+1); 38 bool flag=0; 39 for(i=1;i<=lm;i++){ 40 if(s[i].sum&1)continue; 41 else{ 42 if(s[i+1].sum==s[i].sum){i++;continue;} 43 else {flag=1;break;} 44 } 45 } 46 if(flag){printf("-1\n");return 0;} 47 for(i=1;i<=lm;i++){ 48 if(s[i].sum&1){ 49 for(j=0;j<s[i].sum;j++) 50 q[j*2%s[i].sum]=s[i].p[j]; 51 for(j=0;j<s[i].sum-1;j++) 52 ans[q[j]]=q[j+1]; 53 ans[q[s[i].sum-1]]=q[0]; 54 } 55 else{ 56 int k=i+1; 57 for(j=0;j<s[i].sum;j++){ 58 ans[s[i].p[j]]=s[k].p[j]; 59 ans[s[k].p[j]]=s[i].p[(j+1)%s[i].sum]; 60 } 61 i++; 62 } 63 } 64 for(i=1;i<=n;i++) 65 printf("%d ",ans[i]); 66 return 0; 67 }