Codeforces Round #397 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 mnumbers 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

contest进行的时候一直卡在这道题。知道肯定是构造,但一直没想到合适的办法。结果比赛过后与同学交流,居然全都是用伪证构造过的。构造时只保证满足h(g(x))=f(x)这个条件,构造完成后检验另一个条件是否成立,如果成立则输出,不然就无解。(还没想到严格的证明orz)

 1 #include <iostream>
 2 #include<bits/stdc++.h>
 3 #include <queue>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <algorithm>
 7 using namespace std;
 8 typedef long long ll;
 9 typedef unsigned long long ull;
10 const int MAX=1e5+5;
11 int n;
12 int f[MAX],ff[MAX],g[MAX],h[MAX];
13 int m=0;
14 int main()
15 {
16     scanf("%d",&n);
17     int i;
18     for(i=1;i<=n;i++)
19     {
20         scanf("%d",&f[i]);
21     }
22     for(i=1;i<=n;i++)
23     {
24         if(ff[f[i]]==0)
25         {
26             m++;
27             h[m]=f[i];
28             ff[f[i]]=m;
29         }
30         g[i]=ff[f[i]];
31     }
32     for(i=1;i<=m;i++)
33     {
34         if(g[h[i]]!=i)
35         {
36             printf("-1
");
37             return 0;
38         }
39     }
40     printf("%d
",m);
41     for(i=1;i<=n;i++)
42         printf("%d ",g[i]);
43     puts("");
44     for(i=1;i<=m;i++)
45         printf("%d ",h[i]);
46 
47 }
原文地址:https://www.cnblogs.com/quintessence/p/6399356.html