http://codeforces.com/contest/765/problem/D
这题的化简,不能乱带入,因为复合函数的带入,往往要严格根据他们的定义域的
题目要求出下面两个函数
g[h(x)] = x。这个函数的值域[1, m],定义域[1, n]
h[g(x)] = f(x)。这个函数的值域[1, n],定义域[1, m]
设任意一个数t、和A。使得g[t] = A,也就是有h[A] = t了。
h[A] = h[g(t)] = f(t),那么就是f(t) = t的时候,会使得g[t] = A,h[A] = t
A的值从1...n模拟过去。
这样就能得到g[]和h[]
当然,g[]有些是0,也就是空的,这个时候去找h[]任何一个满足g[pos] = x。就行。
其他的就是细节了。
8
1 2 3 2 1 2 3 2
1 2 3 2 1 2 3 2
5
1 2 2 1 1
1 2 2 1 1
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <assert.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> #include <bitset> const int maxn = 1e6 + 20; int f[maxn]; int g[maxn]; int h[maxn]; int ans[maxn]; int mph[maxn]; void work() { int n; cin >> n; for (int i = 1; i <= n; ++i) cin >> f[i]; int m = 0; for (int i = 1; i <= n; ++i) { if (f[i] == i) { g[i] = ++m; h[m] = i; mph[i] = m; } } if (m == 0) { cout << "-1" << endl; return; } // for (int i = 1; i <= n; ++i) { // if (g[i] == 0) g[i] = 1; // } for (int i = 1; i <= n; ++i) { if (g[i] != 0 && h[g[i]] != f[i]) { cout << -1 << endl; return; } if (g[i] == 0) { if (!mph[f[i]]) { cout << -1 << endl; return; } g[i] = mph[f[i]]; } if (i <= m && g[h[i]] != i && g[h[i]] != 0) { cout << -1 << endl; return; } if (i <= m && g[h[i]] == 0) { g[h[i]] = i; i--; } // i--; } cout << m << endl; for (int i = 1; i <= n; ++i) { cout << g[i] << " "; } cout << endl; for (int i = 1; i <= m; ++i) { cout << h[i] << " "; } cout << endl; } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif work(); return 0; }