题目连接:uva 11174 - Stand in a Line
题目大意:村子里有n个村名民,现在他们要排成一列,处于对长辈的尊敬,他们不能排在自己父亲的前面,有些人的父亲不一定在村子了。问有多少种列的顺序。
解题思路:【算法竞赛入门经典-训练指南】的例题,主要还用到了欧几里得拓展定理求逆元。
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 40005;
const ll MOD = 1e9+7;
int n, m;
ll v[N];
vector<int> g[N];
void init () {
scanf("%d%d", &n, &m);
memset(v, 0, sizeof(v));
for (int i = 0; i <= n; i++)
g[i].clear();
int a, b;
for (int i = 0; i < m; i++) {
scanf("%d%d", &a, &b);
g[b].push_back(a);
}
}
ll dfs(int x) {
if (v[x])
return v[x];
for (int i = 0; i < g[x].size(); i++)
v[x] += dfs(g[x][i]);
return ++v[x];
}
void gcd (ll a, ll b, ll& x, ll& y, ll& d) {
if (b == 0) {
d = a;
x = 1;
y = 0;
} else {
gcd(b, a%b, y, x, d);
y -= x*(a/b);
}
}
int main () {
int cas;
scanf("%d", &cas);
while (cas--) {
init ();
ll ans = 1, b = 1;
for (ll i = 1; i <= n; i++)
ans = (ans * i) % MOD;
for (int i = 1; i <= n; i++)
b = (b * dfs(i)) % MOD;
ll p, k, d = 1;
gcd(b, MOD, p, k, d);
ans = ((ans * p) % MOD + MOD) % MOD;
printf("%lld\n", ans);
}
return 0;
}
uva 11174 - Stand in a Line(逆元+递推)
时间: 2024-10-05 22:31:54