hdu5399Too Simple

//给m个函数
//其对应是自变量x属于{1,2,...n}
//f(x)属于{1,2...3}
//给出其中一些函数,问有多少种不同的函数集合使得
//1<=i<=n  f1(f2(f3...fm(i))) = i
//直接为(m!)^(sum-1)  sum为不知道的函数个数
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 110 ;
typedef long long ll ;
const ll mod = 1e9+7 ;
int map[maxn][maxn] ;
int vis[maxn];
int a[maxn] ;
int main()
{
    //freopen("in.txt" ,"r" ,stdin) ;
    //freopen("out.txt","w" ,stdout);
    int n , m ;
    int t  = 0 ;
    while(~scanf("%d%d" ,&m , &n))
    {
        int sum = 0 ;
        int flag = 0 ;
        for(int i = 1;i <= n;i++)
        {
            memset(vis , 0 , sizeof(vis)) ;
            int tmp ;
            scanf("%d" , &tmp);
            if(tmp == -1)
            sum++;
            else
            {
                map[i][1] = tmp;
                if(tmp < 1 || tmp > m || vis[tmp])flag = 1;
                for(int j = 2;j <= m;j++)
                {
                    scanf("%d" , &map[i][j]) ;
                    if(map[i][j] < 1 || map[i][j] > m || vis[map[i][j]])
                    flag = 1;
                    vis[map[i][j]] = 1;
                }
            }
        }
        if(flag)
        {
            puts("0");
            continue ;
        }
        if(sum)
        {
            ll ans = 1;
            sum--;
            ll tmp = 1 ;
            for(ll i = 1;i <= m;i++)
            tmp = (tmp*i)%mod ;
            while(sum--)
            ans = (ans*tmp)%mod ;
            printf("%lld\n" , ans) ;
            continue ;
        }
        for(int i = 1;i <= m;i++)
        a[i] = i ;
        for(int i = n;i > 0;i--)
          for(int j = 1;j <= m;j++)
          a[j] = map[i][a[j]] ;
        flag = 0 ;
        for(int i = 1;i <= m;i++)
        if(a[i] != i)
        {
            flag = 1;
            break ;
        }
       if(flag)puts("0");
       else puts("1");
    }
    return 0 ;
}

你可能感兴趣的:(hdu5399Too Simple)