D. Artsem and Saunders

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 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.

Input

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).

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 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.

Examples

Input

3
1 2 3

Output

3
1 2 3
1 2 3

Input

3
2 2 2

Output

1
1 1 1
2

Input

2
2 1

Output

-1


题意:给定一个f(x)值域和定义域都属于[1,n],然后给一个g(x),值域属于[1, m],定义域属于[1, n],一个h(x),值域属于[1, n],定义域属于[1, m],并且g(h(x)) = x和h(g(x)) = f(x)成立,求m,求g[1-n], h[1-m]。
题解:构造函数,主要还是数学思想(fuck!!!),用条件h(g(x)) = f(x)来构造h[m]和g[n],再用g(h(x)) = x来验证构造是否成立。
#include <stdio.h> #include <iostream> #include <string.h> #include <math.h> #include <algorithm> #include <stdlib.h> #include <queue> using namespace std; int f[100100], h[100100], g[100100], vis[100100]; int main() { int m, n, i, j; scanf("%d", &n); memset(g, 0, sizeof g); memset(vis, 0, sizeof vis); for (i = 1; i <= n; i++) { scanf("%d", &f[i] ); } m = 0; for (i = 1; i <= n; i++) { if(vis[f[i]] == 0) { m++; h[m] = f[i]; vis[f[i]] = m; } g[i] = vis[f[i]]; } for (i = 1; i <= m; i++) { if (g[h[i]] != i) { printf("-1\n"); return 0; } } printf("%d\n", m); for (i = 1; i <= n; i++) printf("%d ", g[i]); printf("\n"); for (int i = 1; i <= m; i++) printf("%d ", h[i]); printf("\n"); return 0; }

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值