Codeforces Round #397(Div. 1 + Div. 2 combined)D. Artsem and Saunders【思维+乱搞】

来源:互联网 发布:虎牙象棋勇哥是软件 编辑:程序博客网 时间:2024/05/22 00:08

D. Artsem and Saunders
time limit per test
2 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output

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 functionf is defined in integer points 1, ..., x, and all its values are integers from 1 toy.

Now then, you are given a function f: [n] → [n]. Your task is to find a positive integerm, and two functions g: [n] → [m], h: [m] → [n], such thatg(h(x)) = x for all, andh(g(x)) = f(x) for all, or determine that finding these is impossible.

Input

The first line contains an integer n (1 ≤ n ≤ 105).

The second line contains n space-separated integers — valuesf(1), ..., f(n) (1 ≤ f(i) ≤ n).

Output

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 printn numbers g(1), ..., g(n). On the third line printm 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.

Examples
Input
31 2 3
Output
31 2 31 2 3
Input
32 2 2
Output
11 1 12
Input
22 1
Output
-1


题目大意:

给你N个数,表示f(1),f(2),f(3).........f(n);

现在要求你找到合法的两个映射h(x),g(x)。

使得①h(g(x))=f(x)&&②g(h(x))=x;


思路:


1、我们不难分析出来,根据h(g(x))=f(x)这个条件,我们能够很容易想到h(x)=f(x);也不难想到,对于重复的f(x),我们只要有一个h(x)对应就可以了.那么此时我们可以判断出来,对应m的大小,就是f(x)中元素种类的个数。


2、那么是不是m一定是这样呢?显然如果只为了满足第①个条件,这样就够了,但是对于第二个条件我们要对其进行满足是不是可以适当的增加m的大小来改变结果呢?

我们不妨在纸上模拟第二个样例增加一个元素的可能结果:

4

2 2 2 4

发现结果很容易确定:

1 1 1 2

2 4

此时增加出来的结果中,f(4)=4,因为是第二种出现的元素,那么设定g(x)=2,那么恰好能够使得h(2)=4.这是一种可行解。

接下来不妨在纸上模拟下一种情况:
4

2 2 2 3

我们能否通过增加m的大小来使得结果可行呢?枚举大量的方案之后,发现这是不可能完成的任务。

这个时候不难总结出来结论。对于m的大小来讲,其实就是原序列中元素种类的个数。


3、那么接下来的任务就是unique原序列.对于h(x),就是f(x)的unique的结果.再暴力O(m)根据h(x)来得到g(x),最终判断一下这种方案是否能够满足第②个约数条件即可,如果满足,那么此时的序列就是结果,否则就是无解.


Ac代码:


#include<stdio.h>#include<string.h>#include<map>using namespace std;int a[100060];int anspre[100060];int ans[100060];int main(){    int n;    while(~scanf("%d",&n))    {        int cont=1;        map<int ,int >s;        for(int i=0;i<n;i++)        {            scanf("%d",&a[i]);            if(s[a[i]]==0)            {                s[a[i]]=cont;                ans[cont-1]=a[i];                cont++;            }            else continue;        }        int flag=0;        for(int i=0;i<n;i++)anspre[i]=s[a[i]];        for(int i=0;i<cont-1;i++)        {            if(anspre[ans[i]-1]==i+1)continue;            else flag=1;        }        if(flag==1)        {            printf("-1\n");            continue;        }        printf("%d\n",cont-1);        for(int i=0;i<n;i++)        {            printf("%d ",anspre[i]);        }        printf("\n");        for(int i=0;i<cont-1;i++)        {            printf("%d ",ans[i]);        }        printf("\n");    }}






0 0