题目链接:codeforces 765D
Artsem has a friend Saunders from University of Chicago. Saunders presented him with the following problem.
Let [n] denote the set {1, ..., n}. We will also write f: [x] → [y] when a function f is defined in integer points 1, ..., x, and all its values are integers from 1 to y.
Now then, you are given a function f: [n] → [n]. Your task is to find a positive integer m, and two functions g: [n] → [m], h: [m] → [n], such that g(h(x)) = x for all , and h(g(x)) = f(x) for all , or determine that finding these is impossible.
The first line contains an integer n (1 ≤ n ≤ 105).
The second line contains n space-separated integers — values f(1), ..., f(n) (1 ≤ f(i) ≤ n).
If there is no answer, print one integer -1.
Otherwise, on the first line print the number m (1 ≤ m ≤ 106). On the second line print n numbers g(1), ..., g(n). On the third line print m numbers h(1), ..., h(m).
If there are several correct answers, you may output any of them. It is guaranteed that if a valid answer exists, then there is an answer satisfying the above restrictions.
3 1 2 3
3 1 2 3 1 2 3
3 2 2 2
1 1 1 1 2
2 2 1
-1
题目分析:讲起来比较复杂,首先考虑存在性,对于h(g(x))=f(x)遍历所有的x,也就是说f(x)最多有m个值,多于m将不存在,之后考虑假设存在,h(a)=b -> g(h(a))=g(b)=a{1} ->h(g(b))=h(a)=b=f(b){2};首先可以确定了对于所有的h(x)=y,都有y=f(y)。反过来也是如此,因此可以确定h的函数式了,即找出所有f(x)=x的x,同时也可以确定m的值,依次匹配到h(x)中,这里顺序可以不同,同时由{1}可以确定h(a)=b,则g(b)=a,并且假设g(c)=d,则h(g(c))=f(c),c从1到n遍历,所以设th为h的反函数,即h(i)=j,th(j)=i。这样,g(i)=th(f(i)),从1到n循环一遍即可。
//
// main.cpp
// D. Artsem and Saunders
//
// Created by teddywang on 2017/2/14.
// Copyright © 2017年 teddywang. All rights reserved.
//
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[1000010],g[1000010],h[1000010];
int buf[1000010];
int th[1000010];
int n,m;
int main()
{
while(cin>>n)
{
memset(buf,0,sizeof(buf));
m=0;
int a=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&f[i]);
if(buf[f[i]]==0)
{
buf[f[i]]=1;
m++;
}
if(i==f[i])
{
h[++a]=f[i];
g[i]=a;
th[f[i]]=a;
}
}
if(m>a)
{
cout<<-1<<endl;
continue;
}
cout<<m<<endl;
for(int i=1;i<=m;i++)
{
g[h[i]]=i;
int a=h[i];
g[f[a]]=i;
}
for(int i=1;i<=n;i++)
{
g[i]=th[f[i]];
}
for(int i=1;i<n;i++)
{
printf("%d ",g[i]);
}
printf("%d\n",g[n]);
for(int i=1;i<m;i++)
{
printf("%d ",h[i]);
}
printf("%d\n",h[m]);
}
}