[COGS 2353 & 2356] 有标号的DAG计数 容斥原理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[COGS 2353 & 2356] 有标号的DAG计数 容斥原理相关的知识,希望对你有一定的参考价值。
COGS 2353
题意
问 n 个点的带标号 DAG 有多少个.
n <= 5000 .
分析
DAG 的突破口在于度数为 0 的点, 我们每次将其删去, 则还有一些度数为 0 的点.
设 $f_n$ 为 n 个点的带标号 DAG 个数, 奠基 $f_0 = 1$ , 答案为 $f_n$ .
我们考虑容斥原理, 用至少有 1 个度数为 0 的点的 DAG 个数, 减去至少有 2 个度数为 0 的点的 DAG 个数, 加上至少有 3 个度数为 0 的点的 DAG 个数, ...
$$f_n = \sum_{k = 1} ^ n {(-1)} ^ {k - 1} \binom{n}{k} 2 ^ {k (n - k)} f_{n - k}$$ .
实现
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cctype> 5 #define F(i, a, b) for (register int i = (a); i <= (b); i++) 6 7 const int N = 5005; 8 const int MOD = 10007; 9 10 int s, C[N][N], pwr[MOD], f[N]; 11 12 void Prework(void) { 13 C[0][0] = 1; 14 F(i, 1, s) { 15 C[i][0] = 1; 16 F(j, 1, i) 17 C[i][j] = (C[i-1][j] + C[i-1][j-1]) % MOD; 18 } 19 20 pwr[0] = 1; 21 F(i, 1, MOD) 22 pwr[i] = (pwr[i-1] << 1) % MOD; 23 } 24 inline int Pow(int n) { return pwr[n % (MOD - 1)]; } 25 26 int main(void) { 27 freopen("DAG.in", "r", stdin); 28 freopen("DAG.out", "w", stdout); 29 30 scanf("%d", &s), Prework(); 31 32 f[0] = 1; 33 F(n, 1, s) 34 F(k, 1, n) 35 f[n] = (f[n] + (k&1 ? 1LL : -1LL) * C[n][k] * Pow(k*(n-k)) * f[n-k]) % MOD; 36 printf("%d\n", (f[s] + MOD) % MOD); 37 38 return 0; 39 }
以上是关于[COGS 2353 & 2356] 有标号的DAG计数 容斥原理的主要内容,如果未能解决你的问题,请参考以下文章
COGS 1534 [NEERC 2004]K小数 &&COGS 930 [河南省队2012] 找第k小的数 可持久化01Trie
COGS103&tyvj1899 [NOIP2002]矩形覆盖
Bzoj1176:Mokia&Cogs1752:[BOI2007]摩基亚Mokia