【CodeForces 765D】 Artsem and Saunders(数学,构造)

来源:互联网 发布:怎么使用淘宝客 编辑:程序博客网 时间:2024/06/07 15:27

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

题目大意:定义两个函数 g(h(x)) = x 和h(g(x)) = f(x) 给出f(x) 构造 h(x) 和 g(x) 使其满足条件
思路:(我居然能写出D题,莫名兴奋)。g(x) 有 n 个元素, h(x) 有 m 个元素,根据函数关系,可以推出表达式 g(x) = g( f(x) ) ,此式表达 g(x)==g(a),其中a==f(x),  设 g(1)=1,根据表达式从 1 ~n 构造出 g(x) ,构造过程中如果出现与之前矛盾的情况则输出 -1 。第二步根据  h(g(x)) = f(x) 从 1~n 推出 h(x) 的表达式,此过程中如果出现矛盾则输出 -1,完毕。

#include <bits/stdc++.h>#define manx 100005using namespace std;int main(){    int f[manx]={0},h[manx]={0},g[manx]={0},n,m;    scanf("%d",&n);    for (int i=1; i<=n; i++) scanf("%d",&f[i]);    int cot=1;    for (int i=1; i<=n; i++){        if (g[f[i]]) g[i]=g[f[i]];  //g[f[i]]在g[i]之前        else if (g[i]==0) g[i]=cot++;        if(!g[f[i]]) g[f[i]]=g[i]; //g[f[i]]在g[i]之后        else if (g[f[i]]!=g[i]){            printf("-1\n");            return 0;        }    }    m=0;    for (int i=1; i<=n; i++){        if(!h[g[i]]) {            h[g[i]]=f[i];            m++;        }        else if(h[g[i]]!=f[i]){            printf("-1\n");            return 0;        }    }    printf("%d\n",m);    for (int i=1; i<=n; i++)        i==n ? printf("%d\n",g[i]) : printf("%d ",g[i]);    for (int i=1; i<=m; i++)        i==m ? printf("%d\n",h[i]) : printf("%d ",h[i]);    return 0;}


0 0