题意:首先我是懂了的,然后我觉得很难讲清楚就懒得写了,关键理解f1(f2(fm(i)))=i,不懂的戳这里
构造:如果fi(j)不是映射到(1~n),重复或者不在范围内的肯定无解。还有没有-1的情况,模拟一下若不能满足f1(f2(fm(i)))=i,也是不行的。除此之外,那么有k个-1,那么方案数是(n!) ^ (k - 1),因为k-1个可以随便排列,最后一个由之前的确定
/************************************************
* Author :Running_Time
* Created Time :2015-8-18 16:01:25
* File Name :D.cpp
************************************************/
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int MAXN = 1e2 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int a[MAXN][MAXN];
bool vis[MAXN];
ll f[MAXN];
int main(void) { //HDOJ 5399 Too Simple
int n, m; f[1] = 1;
for (int i=2; i<=100; ++i) f[i] = f[i-1] * i % MOD;
while (scanf ("%d%d", &n, &m) == 2) {
int cnt = 0; bool flag = true;
for (int i=1; i<=m; ++i) {
scanf ("%d", &a[i][1]);
if (a[i][1] == -1) {
cnt++; continue;
}
memset (vis, false, sizeof (vis));
vis[a[i][1]] = true;
for (int j=2; j<=n; ++j) {
scanf ("%d", &a[i][j]);
if (vis[a[i][j]]) flag = false;
else vis[a[i][j]] = true;
}
}
if (cnt == 0) {
for (int i=1; i<=n && flag; ++i) {
int p = i;
for (int j=m; j>=1; --j) p = a[j][p];
if (p != i) flag = false;
}
}
if (!flag) {
puts ("0"); continue;
}
ll ans = 1;
for (int i=1; i<cnt; ++i) ans = ans * f[n] % MOD;
printf ("%I64d ", ans);
}
return 0;
}
* Author :Running_Time
* Created Time :2015-8-18 16:01:25
* File Name :D.cpp
************************************************/
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int MAXN = 1e2 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int a[MAXN][MAXN];
bool vis[MAXN];
ll f[MAXN];
int main(void) { //HDOJ 5399 Too Simple
int n, m; f[1] = 1;
for (int i=2; i<=100; ++i) f[i] = f[i-1] * i % MOD;
while (scanf ("%d%d", &n, &m) == 2) {
int cnt = 0; bool flag = true;
for (int i=1; i<=m; ++i) {
scanf ("%d", &a[i][1]);
if (a[i][1] == -1) {
cnt++; continue;
}
memset (vis, false, sizeof (vis));
vis[a[i][1]] = true;
for (int j=2; j<=n; ++j) {
scanf ("%d", &a[i][j]);
if (vis[a[i][j]]) flag = false;
else vis[a[i][j]] = true;
}
}
if (cnt == 0) {
for (int i=1; i<=n && flag; ++i) {
int p = i;
for (int j=m; j>=1; --j) p = a[j][p];
if (p != i) flag = false;
}
}
if (!flag) {
puts ("0"); continue;
}
ll ans = 1;
for (int i=1; i<cnt; ++i) ans = ans * f[n] % MOD;
printf ("%I64d ", ans);
}
return 0;
}