首先可以把题目转化一下:把树拆成若干条链,每条链的颜色为其所在的树的颜色,然后排放所有的链成环,求使得相邻位置颜色不同的排列方案数。

然后本题分为两个部分:将一棵树分为1~n条不相交的链的方案数;将这些链安排顺序使得不存在两条相邻的链来自同一棵树。

第一部分显然可以O(n2)树形DP,f[i][j][0/1/2]表示i及其子树j条链,i向儿子连出0/1/2条边的方案数,然后直接背包DP即可。看似O(n3)的树形背包DP其实是O(n2)的。证明复杂度:其实DP时只循环到sz[u]/sz[v]即可,然后可以把每个转移视为儿子v内子树的每个节点和节点u内v外节点组成的点对,于是全部DP完就是枚举了所有的点对,复杂度显然O(n2)。

第二部分,考虑n个点的树划分成i条链的方案是f[i],如果不考虑环只考虑链其对应的指数生成函数为Σf[i]i!(Σ(-1)i-jC(i-1,i-j)xj/j!),其中i∈[1,n],j∈[1,i]。拓展到环上,钦定一棵树作为开头,如果该颜色有i条链,则被算了i次,然后其指数生成函数为:Σf[i](i-1)!(Σ(-1)i-jC(i-1,i-j)xj-1/(j-1)!),其中i∈[1,n],j∈[1,i]。减去首尾同色后,生成函数是这样的:Σf[i](i-1)!(Σ(-1)i-jC(i-1,i-j)xj-2/(j-2)!),其中i∈[2,n],j∈[2,i]。然后暴力卷积即可。

#include<bits/stdc++.h>
using namespace std;
const int N=,mod=;
int n,m,sum,ans,fac[N],inv[N],sz[N],f[N][N][],g[N],tmp[N][],dp[][N],b[N];
vector<int>G[N];
int qpow(int a,int b)
{
int ret=;
while(b)
{
if(b&)ret=1ll*ret*a%mod;
a=1ll*a*a%mod,b>>=;
}
return ret;
}
void dfs(int u,int fa)
{
sz[u]=,f[u][][]=;
for(int i=;i<G[u].size();i++)
if(G[u][i]!=fa)
{
int v=G[u][i];
dfs(v,u);
for(int j=;j<=sz[u]+sz[v];j++)tmp[j][]=tmp[j][]=tmp[j][]=;
for(int j=;j<=sz[u];j++)
for(int k=;k<=sz[v];k++)
{
tmp[j+k][]=(tmp[j+k][]+1ll*f[u][j][]*(f[v][k][]+2ll*f[v][k][]+2ll*f[v][k][]))%mod;
tmp[j+k-][]=(tmp[j+k-][]+1ll*f[u][j][]*(f[v][k][]+f[v][k][]))%mod;
tmp[j+k][]=(tmp[j+k][]+1ll*f[u][j][]*(f[v][k][]+2ll*f[v][k][]+2ll*f[v][k][]))%mod;
tmp[j+k-][]=(tmp[j+k-][]+1ll*f[u][j][]*(f[v][k][]+f[v][k][]))%mod;
tmp[j+k][]=(tmp[j+k][]+1ll*f[u][j][]*(f[v][k][]+2ll*f[v][k][]+2ll*f[v][k][]))%mod;
}
sz[u]+=sz[v];
for(int j=;j<=sz[u];j++)f[u][j][]=tmp[j][],f[u][j][]=tmp[j][],f[u][j][]=tmp[j][];
}
}
int C(int a,int b){return a<b?:1ll*fac[a]*inv[b]%mod*inv[a-b]%mod;}
int S(int a,int b){return (!a&&!b)?:1ll*fac[a]*C(a-,a-b)%mod;}
int main()
{
fac[]=;for(int i=;i<=;i++)fac[i]=1ll*fac[i-]*i%mod;
for(int i=;i<=;i++)inv[i]=qpow(fac[i],mod-);
scanf("%d",&m);
dp[][]=;
for(int p=;p<=m;p++)
{
scanf("%d",&n);
for(int i=;i<=n;i++)G[i].clear();
for(int i=,x,y;i<n;i++)scanf("%d%d",&x,&y),G[x].push_back(y),G[y].push_back(x);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
f[i][j][]=f[i][j][]=f[i][j][]=;
dfs(,);
memset(g,,sizeof g);
for(int i=;i<=n;i++)g[i]=(f[][i][]+2ll*f[][i][]+2ll*f[][i][])%mod;
if(p!=m)
{
memset(b,,sizeof b);
for(int j=;j<=n;j++)
if(g[j])for(int k=,t=;k<=j;k++,t=mod-t)
b[j-k]=(b[j-k]+1ll*t*S(j,j-k)%mod*g[j])%mod;
for(int i=;i<=sum;i++)
if(dp[p-][i])for(int j=;j<=n;j++)
dp[p][i+j]=(dp[p][i+j]+1ll*C(i+j,j)*b[j]%mod*dp[p-][i])%mod;
}
else{
memset(b,,sizeof b);
for(int j=;j<=n;j++)
if(g[j])for(int k=,t=;k<j;k++,t=mod-t)
b[j--k]=(b[j--k]+1ll*t*S(j-,j-k-)%mod*g[j])%mod;
for(int i=;i<=sum;i++)
if(dp[p-][i])for(int j=;j<=n;j++)
ans=(ans+1ll*C(i-+j,j)*b[j]%mod*dp[p-][i])%mod;
}
sum+=n;
}
printf("%d",ans);
}

[JSOI2019]神经网络(树形DP+容斥+生成函数)的更多相关文章

  1. P5405-[CTS2019]氪金手游【树形dp,容斥,数学期望】

    前言 话说在\(Loj\)下了个数据发现这题的名字叫\(fgo\) 正题 题目链接:https://www.luogu.com.cn/problem/P5405 题目大意 \(n\)张卡的权值为\(1 ...

  2. HDU - 5977 Garden of Eden (树形dp+容斥)

    题意:一棵树上有n(n<=50000)个结点,结点有k(k<=10)种颜色,问树上总共有多少条包含所有颜色的路径. 我最初的想法是树形状压dp,设dp[u][S]为以结点u为根的包含颜色集 ...

  3. bzoj 4455 [Zjoi2016]小星星 树形dp&容斥

    4455: [Zjoi2016]小星星 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 643  Solved: 391[Submit][Status] ...

  4. [USACO12FEB] 附近的牛 Nearby Cows - 树形dp,容斥

    给你一棵 \(n\) 个点的树,点带权,对于每个节点求出距离它不超过 \(k\) 的所有节点权值和 \(m_i\) 随便定一个根,设\(f[i][j]\)表示只考虑子树,距离为\(j\)的权值和,\( ...

  5. bzoj 3622 DP + 容斥

    LINK 题意:给出n,k,有a,b两种值,a和b间互相配对,求$a>b$的配对组数-b>a的配对组数恰好等于k的情况有多少种. 思路:粗看会想这是道容斥组合题,但关键在于如何得到每个a[ ...

  6. 【BZOJ 4665】 4665: 小w的喜糖 (DP+容斥)

    4665: 小w的喜糖 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 94  Solved: 53 Description 废话不多说,反正小w要发喜 ...

  7. [Luogu P1450] [HAOI2008]硬币购物 背包DP+容斥

    题面 传送门:https://www.luogu.org/problemnew/show/P1450 Solution 这是一道很有意思的在背包里面做容斥的题目. 首先,我们可以很轻松地想到暴力做背包 ...

  8. 5.15 省选模拟赛 容斥 生成函数 dp

    LINK:5.15 T2 个人感觉生成函数更无脑 容斥也好推的样子. 容易想到每次放数和数字的集合无关 所以得到一个dp f[i][j]表示前i个数字 逆序对为j的方案数. 容易得到转移 使用前缀和优 ...

  9. HDU 5838 (状压DP+容斥)

    Problem Mountain 题目大意 给定一张n*m的地图,由 . 和 X 组成.要求给每个点一个1~n*m的数字(每个点不同),使得编号为X的点小于其周围的点,编号为.的点至少大于一个其周围的 ...

随机推荐

  1. UVA 10054 The Necklace 转化成欧拉回路

    题意比较简单,给你n个项链碎片,每个碎片的两半各有一种颜色,最后要把这n个碎片串成一个项链,要求就是相邻碎片必须是同种颜色挨着. 看了下碎片总共有1000个,颜色有50种,瞬间觉得普通方法是无法在可控 ...

  2. 启动运行python3时 UnicodeDecodeError: 'gbk' codec can't decode byte 0xa2 in position 170: illegal multibyte sequence

    重现 在cmd中输入Python,运行后,出现以下错误: Python 3.7.3 (default, Mar 27 2019, 17:13:21) [MSC v.1915 64 bit (AMD64 ...

  3. JavaWeb之搭建自己的MVC框架(三)

    1. 前言         在前两节的内容中,我们完成了一个基本的框架搭建.但是如果我们在前端请求中增加参数,我们要怎么传递到后台方法呢?接下来我们就来研讨这部分内容. 2. 实现         ( ...

  4. CCCC 红色警报

    题意: 战争中保持各个城市间的连通性非常重要.本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报.注意:若该国本来就不完全连通,是分裂的k个区域,而失去一个 ...

  5. ADC分辨率

    转载:http://www.rationmcu.com/elecjc/1874.html 今天给大家简单介绍一下ADC器件的常识. ADC,模数转换器,功能是把模拟电压转换成数字量. 概念听的模糊,说 ...

  6. 为什么ApplePay在中国一直火不起来?

    今年7月,易观发布<中国第三方移动支付市场2018年第1季度监测报告>.报告显示,2018年第一季度支付宝以53.76%的市场份额占据移动支付头把交椅,腾讯金融(微信支付)则以38.95% ...

  7. AT2000 Leftmost Ball 解题报告

    题面 给你n种颜色的球,每个球有k个,把这n*k个球排成一排,把每一种颜色的最左边出现的球涂成白色(初始球不包含白色),求有多少种不同的颜色序列,答案对1e9+7取模 解法 设\(f(i,\;j)\) ...

  8. 毕设问题 ---链接Dreamweaver和eclipse

    在eclipse里面新建站点   https://blog.csdn.net/Slash_youth  我是一个搬运工  哈哈哈

  9. phpmyadmin拿网站shell

    开门见山 1. 找到一个赌博网站,发现存在php探针界面,在下面输入密码尝试用弱口令进行连接,尝试是否成功 失败的结果是这样. 2. 成功! 3. 连接成功的,点击phpMyAdmin管理,进行弱口令 ...

  10. min25筛学习笔记

    min25筛简介:用来求积性函数F(x)前缀和的,复杂度O(n0.75/logn),大概能求n<=1010. 记一个数x的最小质因子为R(x),所以当x不为质数时,R(x)<=√x这是废话 ...