Codeforces Round #397 D题Artsem and Saunders(构造法)解题报告
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.
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).
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.
3
1 2 3
3
1 2 3
1 2 3
3
2 2 2
1
1 1 1
2
2
2 1
-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\n"); 37 return 0; 38 } 39 } 40 printf("%d\n",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 }