您的位置:首页 > 其它

hdu5399(计数)

2015-08-19 15:13 183 查看
题意:

有n个数字,并给出m个函数变化;

如果给出的函数变化是-1,代表这个函数不确定,可以任意写;

问使

f1(f2(......fm(i))) = i;

成立的所有情况有几种;

思路:

现将确定的函数模拟一边;得到的值如果有重复映射,则0种可能,因为一旦又重复映射,我们就不能映射出1到n所有的值;

然后看不确定的函数个数;只需要留一个用来做调整,剩下的都是1到n的全排列;

#include <cstdio>
#include <cstring>

#define ll long long
const int N = 105;
const int MOD = 1e9 + 7;

int f

, n, m, tmp
;
ll A
;

void change(int* F) {
for (int i = 1; i <= n; i++)
tmp[i] = F[tmp[i]];
}
bool judge(int k) {
for (int i = 1; i <= n; i++)
tmp[i] = i;
for (int i = k - 1; i >= 0; i--)
change(f[i]);
int vis
;
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++) {
if(vis[tmp[i]])
return false;
vis[tmp[i]] = 1;
}
return true;
}
int main() {
A[1] = 1;
for (int i = 2; i <= N; i++) {
A[i] = A[i - 1] * i % MOD;
}
while (scanf("%d%d", &n, &m) == 2) {
memset(f, 0, sizeof(f));
int k = 0, c = 0;
for (int i = 1; i <= m; i++) {
scanf("%d", &f[k][1]);
if(f[k][1] == -1) {
c++;
continue;
}
for (int j = 2; j <= n; j++) {
scanf("%d", &f[k][j]);
}
k++;
}
bool ok = judge(k);
if (!ok) {
printf("0\n");
continue;
}
if (c == 0) {
int flag = 0;
for (int i = 1; i <= n; i++)
if (tmp[i] != i) {
flag = 1;
break;
}
if (flag) {
printf("0\n");
continue;
}
}
ll ans = 1;
for (int i = 1; i < c; i++) {
ans = ans * A
% MOD;
}
printf("%lld\n", ans);
}
}


f1(f2(⋯fm(i)))=i

f1(f2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: