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; }