zoukankan      html  css  js  c++  java
  • [ARC101C] Ribbons On the Tree

    [题目链接]

    https://atcoder.jp/contests/arc101/tasks/arc101_c

    [题解]

    直接做比较麻烦。

    考虑一个最简单的容斥原理 : (ans = sum{(-1)^{|S|}f(S)}) , 其中 (f(S)) 表示 (S) 集合内所有边都不选的方案。

    考虑对于一个大小为 (N) ((N) 为偶数) 的联通块随便连的方案数 , 其贡献是 ((N - 1) * (N - 3) * ... * 1)。 那么 (f(S)) 就是分割成的联通块的贡献乘积。

    不妨用 (dp(i , j)) 表示以 (i) 为根的子树 , 现在 (i) 所在联通块大小是 (j) 的贡献和 (不包括当前联通块的贡献)。 转移的时候乘上容斥系数。 那么只需要做一个简单的树上背包即可。

    时间复杂度 : (O(N ^ 2))

    [代码]

    #include <bits/stdc++.h>
     
    using namespace std;
     
    typedef long long LL;
     
    const int MN = 5005 , mod = 1e9 + 7;
     
    int N , coef[MN] , f[MN][MN] , siz[MN];
    vector < int > a[MN];
     
    inline void inc(int &x , int y) {
    	x = x + y < mod ? x + y : x + y - mod;
    }
    inline void dec(int &x , int y) {
    	x = x - y >= 0 ? x - y : x - y + mod;
    }
    inline void solve(int u , int fa) {
    	f[u][1] = 1; siz[u] = 1;
    	for (int v : a[u]) 
    		if (v != fa) {
    			solve(v , u);
    			static int g[MN];
    			for (int i = 1; i <= siz[u] + siz[v]; ++i) g[i] = 0;
    			for (int i = 1; i <= siz[u]; ++i) {
    				for (int j = 1; j <= siz[v]; ++j) {
    					dec(g[i] , 1ll * f[u][i] * coef[j] % mod * f[v][j] % mod);
    					inc(g[i + j] , 1ll * f[u][i] * f[v][j] % mod);
    				}
    			}
    			siz[u] += siz[v];
    			for (int i = 1; i <= siz[u]; ++i) f[u][i] = g[i];
    		}
    }
     
    int main() { 
    	
    	scanf("%d" , &N);
    	for (int i = 1; i < N; ++i) {
    		int u , v;
    		scanf("%d%d" , &u , &v);
    		a[u].emplace_back(v) , a[v].emplace_back(u);
    	}
    	coef[0] = 1;
    	for (int i = 2; i <= N; i += 2) coef[i] = 1ll * coef[i - 2] * (i - 1) % mod;
    	solve(1 , 0); int ans = 0;
    	for (int i = 2; i <= N; i += 2) 
    		inc(ans , 1ll * coef[i] * f[1][i] % mod);
    	printf("%d
    " , ans);
    	return 0; 
    }
  • 相关阅读:
    [转]xna 3.1 to xna 4.0
    office 2010 激活信息查看
    Windows 8 Release Preview下载地址
    常用书籍推荐与下载地址
    禁用Windows7脱机文件的方法
    [转]DEM数据和影像数据下载汇总
    打工是最愚蠢的投资——李嘉诚在深圳大梅沙演讲
    j截图Code
    BYTE与_int64转换
    英语中of和for用法有什么区别?
  • 原文地址:https://www.cnblogs.com/evenbao/p/14033859.html
Copyright © 2011-2022 走看看