Codeforces 765D Artsem and Saunders 构造

来源:互联网 发布:伊芙蕾雅淘宝店 编辑:程序博客网 时间:2024/06/11 03:19

点击打开链接

题意:给出n 和 f[]  求出函数g,h  满足 g[h[x]]=x && h[g[x]]=f[x]   h定义域为1~m 值域为1~n

g[h[g[x]]]=g[f[x]]=g[x]

g[x]=g[f[x]]  -> h[g[x]]=f[x]=h[g[f[x]]]=f[f[x]]  得当两个等式成立即有解时:有f[x]=f[f[x]]


构造

f[x]=f[f[x]] 若f[x]=y 则f[x]=f[y]=y时成立 


假设:若h[m]=x 则g[h[m]]=g[x]=m  -> h[g[x]]=f[x]=h[m]=x 则f[x]=x

当x=f[x]时:令h[m]=x g[x]=m 则条件g[h[m]]=g[x]=m , h[g[x]]=h[m]=x=f[x]也成立


若g[y]还未求出则 由于f[y]=f[x]=x g[f[y]]=g[f[x]] 由于g[f[x]]在x==f[x]时求出 由前面等式知道令g[y]=g[f[y]]即可

#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N=2e6+50;int f[N],g[N],h[N];int main(){int n;while(cin>>n){bool flag=true;int m=0;memset(g,0,sizeof(g));for(int i=1;i<=n;i++)scanf("%d",&f[i]);for(int i=1;i<=n;i++){if(f[i]!=f[f[i]])flag=false;if(f[i]==i){h[++m]=i;g[i]=m;}}for(int i=1;i<=n;i++){if(g[i]==0)g[i]=g[f[i]]; }if(flag){cout<<m<<endl;for(int i=1;i<=n;i++)printf("%d ",g[i]);printf("\n");for(int i=1;i<=m;i++)printf("%d ",h[i]);printf("\n");}elseputs("-1");}return 0;}



0 0
原创粉丝点击