D. Artsem and Saunders

一个变换题

给定f(x),[1,n]->[1,n]

构造g(x),h(x)满足:

g(h(x))=x [1,n]->[1,m]

h(g(x))=f(x) [1,m]->[1,n]

根据已知条件,等效替换变形:

h(g(h(x)))=f(h(x))

=>h(x)=f(h(x))

=>h(g(x))=f(h(g(x)))

=>f(x)=f(f(x)) //是不是有点类似并查集找爸爸

另一方面:

g(h(g(x)))=g(x)

=>g(x)=g(f(x))

这里我们又可以发现f,g,h三个函数的值域其实都是[1,m],等价于将n个元素分为m类

那么题目意思是不是可以转化成:

f(i):找i这个元素的爸爸元素是谁

g(i):找元素i属于哪一类

h(i):找第i类的爸爸元素是谁

这不就是很经典的(排名<<=>>权值)互换函数么



int n, m;
int f[N], g[N], h[N];
int vis[N];

int main()
{
#ifndef ONLINE_JUDGE
    file("test");
#endif
    sdf(n);
    For(i, 1, n) sdf(f[i]);
    For(i, 1, n)
    {
        if (f[f[i]] != f[i])
        {
            cout << -1;
            return 0;
        }
        if (!vis[f[i]])
            h[++m] = f[i], g[f[i]] = m,vis[f[i]]=1;
        g[i] = g[f[i]];
    }
    cout << m << endl;
    For(i, 1, n) cout << g[i] << " ";
    cout << endl;
    For(i, 1, m) cout << h[i] << " ";
posted @ 2018-10-04 02:05  planche  阅读(132)  评论(0编辑  收藏  举报