HDU 5399 Too Simple (数学规律+模拟细节)

Too Simple

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1903    Accepted Submission(s): 626


 

Problem Description

Rhason Cheung had a simple problem, and asked Teacher Mai for help. But Teacher Mai thought this problem was too simple, sometimes naive. So she ask you for help.

Teacher Mai has m functions f1,f2,⋯,fm:{1,2,⋯,n}→{1,2,⋯,n} (that means for all x∈{1,2,⋯,n},f(x)∈{1,2,⋯,n} ). But Rhason only knows some of these functions, and others are unknown.

She wants to know how many different function series f1,f2,⋯,fm there are that for every i(1≤i≤n) ,f1(f2(⋯fm(i)))=i . Two function series f1,f2,⋯,fm and g1,g2,⋯,gm are considered different if and only if there exist i(1≤i≤m),j(1≤j≤n) ,fi(j)≠gi(j) .

 

 

Input

For each test case, the first lines contains two numbers n,m(1≤n,m≤100) .

The following are m lines. In i -th line, there is one number −1 or n space-separated numbers.

If there is only one number −1 , the function fi is unknown. Otherwise the j -th number in the i -th line means fi(j) .

 

 

Output

For each test case print the answer modulo 109+7 .

 

 

Sample Input

 

3 3 1 2 3 -1 3 2 1

 

 

Sample Output

 
1

Hint

The order in the function series is determined. What she can do is to assign the values to the unknown functions.

 

 

Author

xudyh

 

 

Source

2015 Multi-University Training Contest 9

 

 

Recommend

wange2014   |   We have carefully selected several similar problems for you:  6447 6446 6445 6444 6443 

 

#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;

#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)

#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define ll long long

const int  maxn =1e3+5;
const int mod=1e9+7;
/*
题目大意:有m个函数映射,有些映射未知,
要求有多少种这样的映射使得最后组成的映射是f(x)=x。

细节很多,模拟不难,
首先映射输入每一次输入都要是满射
并且无越界,其次就是一旦有-1的存在,
那么组合数固定,不管之前的函数映射是什么样的,
只要最后一个-1映射填好就可以恢复关系,
然后就是一种没有-1的情况,
这种情况要自己模拟判断每一个数是否映射回去。

这题就是细节比较多。

*/

ll gcd(ll x,ll y) { return y==0?x:gcd(y,x%y); }
ll powmod(ll x,ll y){ll t;for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod;return t;}

int n,m,x;
ll fac[maxn];

int cnt,vis[105];
int mp[105][105],tp[105];
int flag;

int main()
{
    fac[0]=1; for(int i=1;i<105;i++) fac[i]=fac[i-1]*i%mod;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        cnt=flag=0;
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&mp[i][1]);vis[mp[i][1]]=1;
            if(mp[i][1]==-1) {cnt++;continue;}
            else
            {
                for(int j=2;j<=n;j++) scanf("%d",&mp[i][j]),vis[mp[i][j]]=1;///判断有无重复数字
                for(int j=1;j<=n;j++) if(vis[j]==0) { flag=1; break; }
            }
             memset(vis,0,sizeof(vis));
        }
        if(flag==1) puts("0");
        else if(cnt==0)
        {
            for(int i=1;i<=n;i++)
            {
                int tp=i;
                for(int j=m;j>=1;j--)  tp=mp[j][tp];
                if(tp!=i) {flag=1;break;}
            }
            printf("%d\n",1-flag);
        }
        else printf("%lld\n",powmod(fac[n],cnt-1));
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值