http://codeforces.com/problemset/problem/765/D
题意:
有一个函数f,f: [n] → [n] 的意思就是定义域为【1,n】,每个x值对应于【1,n】内的一个值(后面的意思也是如此)。现在确定是否存在这样的一个m以及函数h和g,使得满足上述要求。
思路:
对于h(g(x)) = f(x) ,因为x属于【1,n】,所欲f函数的所有值h函数都要包括,既然如此的话,那么f函数中有多少个不同的值,那么m的值就是多大,只需要让h(1),h(2)...依次等于这些值即可(再多其实也已经没有意义了)。
确定了h函数后,我们也就能够推出g函数了,只需要让f函数中的值做个映射即可,具体可以参见代码。确定了h和g函数之后,再用第二个式子判断一下是否满足要求。
1 #include<iostream> 2 #include<cstdio> 3 #include<map> 4 using namespace std; 5 const int maxn = 1e6+5; 6 7 map<int,int> mp; 8 9 int a[maxn],g[maxn],h[maxn]; 10 11 int main() 12 { 13 //freopen("in.txt","r",stdin); 14 int n; 15 scanf("%d",&n); 16 int tot = 0; 17 mp.clear(); 18 for(int i=1;i<=n;i++) 19 { 20 scanf("%d",&a[i]); 21 if(mp[a[i]]==0) 22 { 23 mp[a[i]] = ++tot; 24 h[tot] = a[i]; 25 } 26 } 27 for(int i=1;i<=n;i++) g[i] = mp[a[i]]; 28 bool flag = true; 29 for(int i=1;i<=tot;i++) 30 { 31 if(g[h[i]]!=i) {flag = false;break;} 32 } 33 if(!flag) puts("-1"); 34 else 35 { 36 printf("%d ",tot); 37 for(int i=1;i<=n;i++) printf("%d%c",g[i],i!=n?' ':' '); 38 for(int i=1;i<=tot;i++) printf("%d%c",h[i],i!=tot?' ':' '); 39 } 40 return 0; 41 }