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

[XSY 1538] 连在一起的幻想乡

时间:2017-08-15 21:48:59      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:pre   ons   define   end   连通块   cstring   code   log   include   

题意

  给定 $n$ , 求所有 $n$ 个点的简单连通图的边数的平方的和.

  $n \le 2000$ .

 

分析

  $(x + y) ^ 2 = x ^ 2 + 2xy + y ^ 2$ .

  我们合并的时候, 要对所有的 $x$ 和 $y$ 进行求和.

  $\sum [(x + y) ^ 2] = \sum (x ^ 2) \sum (y ^ 0) + 2 \sum x \sum y + \sum (x ^ 0) \sum (y ^ 2)$ .

 

  设 $h_0[n]$ 为 $n$ 个点的简单图的个数.

  $h_0[n] = 2 ^ {\frac{n(n-1)}{2}}$ .

 

  设 $h_1[n]$ 为 $n$ 个点的简单图的边数的和.

  $h_1[n] = \frac{n(n-1)}{2} 2 ^ {\frac{n(n-1)}{2} - 1}$ .

 

  设 $h_2[n]$ 为 $n$ 个点的简单图的边数的平方的和.

  我们考虑枚举与 $1$ 号点相连的边的数量.

  $h_2[n] = \sum_{i = 0} ^ {n-1} \binom{n-1}{i} (i \times i \times h_0[n-1] + 2 \times i \times h_1[n-1] + h_2[n-1])$ .

 

  设 $f_0[n]$ 为 $n$ 个点的简单连通图的个数.

  我们考虑用总的连通图的个数, 减掉不合法的, 不合法的按照与 $1$ 号点所在的连通块个数进行分类.

  $f_0[n] = h_0[n] - \sum_{i = 1} ^ {n-1} \binom{n-1}{i-1} f_0[i] \times h_0[n-i]$ .

 

  设 $f_1[n]$ 为 $n$ 个点的简单连通图的边数的和.

  $f_1[n] = h_1[n] - \sum_{i = 1} ^ {n-1} \binom{n-1}{i-1} (f_0[i] \times h_1[n-i] + f_1[i] \times h_0[n-i])$ .

 

  设 $f_2[n]$ 为 $n$ 个点的简单连通图的边数的平方的和.

  $f_2[n] = h_2[n] - \sum_{i = 1} ^ {n-1} \binom{n-1}{i-1} (f_2[i] \times h_0[n-i] + 2 \times f_1[i] \times h_1[n-i] + f_0[i] \times h_2[n-i])$ .

 

实现

 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 inline int rd(void) {
 7     int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == -) f = -1;
 8     int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-0; return x*f;
 9 }
10 
11 const int N = 1005;
12 
13 int s, MOD;
14 int c[N][N], h0[N], h1[N], h2[N], f0[N], f1[N], f2[N];
15 
16 inline int pwr(int j) {
17     int mul = 1; for (int i = 2; j > 0; j >>= 1, i = 1LL * i * i % MOD) if (j & 1) mul = 1LL * mul * i % MOD; return mul;
18 }
19 
20 int main(void) {
21     #ifndef ONLINE_JUDGE
22         freopen("xsy1538.in", "r", stdin);
23     #endif
24     
25     scanf("%d %d", &s, &MOD);
26     
27     F(i, 0, s) {
28         c[i][0] = 1;
29         F(j, 1, i)
30             c[i][j] = (c[i-1][j] + c[i-1][j-1]) % MOD;
31     }
32     
33     F(n, 0, s)
34         h0[n] = pwr(n * (n-1) / 2);
35     
36     F(n, 0, s)
37         h1[n] = 1LL * n * (n-1) / 2 * pwr(n * (n-1) / 2 - 1) % MOD;
38     
39     F(n, 0, s)
40         F(i, 0, n-1) {
41             int t = (1LL * i * i * h0[n-1] + 2LL * i * h1[n-1] + h2[n-1]) % MOD;
42             h2[n] = (h2[n] + 1LL * c[n-1][i] * t) % MOD;
43         }
44     
45     F(n, 0, s) {
46         f0[n] = h0[n];
47         F(i, 1, n-1) {
48             int t = 1LL * f0[i] * h0[n-i] % MOD;
49             f0[n] = (f0[n] - 1LL * c[n-1][i-1] * t) % MOD;
50         }
51     }
52     
53     F(n, 0, s) {
54         f1[n] = h1[n];
55         F(i, 1, n-1) {
56             int t = (1LL * f1[i] * h0[n-i] + 1LL * f0[i] * h1[n-i]) % MOD;
57             f1[n] = (f1[n] - 1LL * c[n-1][i-1] * t) % MOD;
58         }
59     }
60     
61     F(n, 0, s) {
62         f2[n] = h2[n];
63         F(i, 1, n-1) {
64             int t = (1LL * f2[i] * h0[n-i] + 2LL * f1[i] * h1[n-i] + 1LL * f0[i] * h2[n-i]) % MOD;
65             f2[n] = (f2[n] - 1LL * c[n-1][i-1] * t) % MOD;
66         }
67     }
68     printf("%d\n", (f2[s] + MOD) % MOD);
69     
70     return 0;
71 }

 

[XSY 1538] 连在一起的幻想乡

标签:pre   ons   define   end   连通块   cstring   code   log   include   

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

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