题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5399

题意:求满足f1(f2(...(fm(i))...))=i的未知的函数有多少种可能。

解法:已经膜得如此明显了。。答案是(n!)^(m-1),m为-1的个数,因为m个不确定的函数,其中的m-1个固定了,那么还有一个也就固定了。每个不确定的都有n!种方案。

如果m为0,则有0种或者1种方案。也就是要看当前的一层一层能否推到f1(f2(...(fm(i))...))=i。要注意:当某个f里1..n没有全部出现时,即有重复数字时,答案是0。这个题要特殊考虑的情况超级多,要特别小心。


#include <bits/stdc++.h>
using namespace std;
//ans = (n!)^(m-1)
typedef long long LL;
const LL mod = 1e9+7;
LL qsm(LL a, LL n)
{
    LL ret = 1;
    while(n)
    {
        if(n&1) ret=ret*a%mod;
        a = a*a%mod;
        n>>=1;
    }
    return ret;
}
LL fac[110], f[110][110], cur[110];
int n, m;

int main()
{
    fac[0] = 1;
    for(int i=1; i<=100; i++)
    {
        fac[i] = fac[i-1]*i%mod;
    }
    while(~scanf("%d %d", &n,&m))
    {
        LL cnt = 0;
        LL ans = 1;
        for(int i=1; i<=m; i++)
        {
            scanf("%lld", &f[i][1]);
            if(f[i][1]==-1)
            {
                cnt++;
            }
            else
            {
                for(int j=2; j<=n; j++)
                {
                    scanf("%lld", &f[i][j]);
                    if(ans)
                    {
                        for(int k = 1; k<j; k++)
                        {
                            if(f[i][k]==f[i][j])
                            {
                                ans=0;
                            }
                        }
                    }
                }
            }
        }
        if(ans == 1)
        {
            if(cnt == 0)
            {
                for(int i=1; i<=n; i++) cur[i]=i;
                for(int i=m; i>=1; i--)
                {
                    for(int j=1; j<=n; j++)
                    {
                        cur[j]=f[i][cur[j]];
                    }
                }
                for(int i=1; i<=n; i++)
                {
                    if(cur[i]!=i)
                    {
                        ans=0;
                        break;
                    }
                }
            }
            else
            {
                ans = qsm(fac[n], cnt-1);
            }
        }
        if(ans < 0) ans+=mod;
        printf("%lld\n", ans);
    }
    return 0;
}