码迷,mamicode.com
首页 > 其他好文 > 详细

[COGS 2353 & 2356] 有标号的DAG计数 容斥原理

时间:2017-08-19 12:37:47      阅读:383      评论:0      收藏:0      [点我收藏+]

标签:ret   gis   题意   多少   cstring   stdin   cst   $$   inline   

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计数 容斥原理

标签:ret   gis   题意   多少   cstring   stdin   cst   $$   inline   

原文地址:http://www.cnblogs.com/Sdchr/p/7395849.html

(0)
(1)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!