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

然后本题分为两个部分:将一棵树分为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. python的库有多少个?python有多少个模块?

    这里列举了大概500个左右的库: !   Chardet字符编码探测器,可以自动检测文本.网页.xml的编码. colorama主要用来给文本添加各种颜色,并且非常简单易用. Prettytable主 ...

  2. 十一、CI框架之输出用户IP地址

    一.代码如下: 二.效果如下: 不忘初心,如果您认为这篇文章有价值,认同作者的付出,可以微信二维码打赏任意金额给作者(微信号:382477247)哦,谢谢.

  3. SASS - 输出格式

    SASS – 简介 SASS – 环境搭建 SASS – 使用Sass程序 SASS – 语法 SASS – 变量 SASS- 局部文件(Partial) SASS – 混合(Mixin) SASS ...

  4. INSTALL_FAILED_SHARED_USER_INCOMPATIBLE错误解决

    Target device: smartisan-yq601-3fa1a5dcInstalling APK: /Users/wangliang/workspace/emm-android/build/ ...

  5. SpringBoot项目 org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Jetty servlet container报错

    SpringBoot项目启动报错 ERROR 2172 --- [ main] o.s.boot.SpringApplication : Application startup failed org. ...

  6. zabbix监控日志关键字

    1 添加zabbix监控项目 A.选择类型为“”zabbix客户端(主动式)“” B.键值: xx_log.log 为日志的绝对路径 connectException 为关键字 ---需根据自己需要定 ...

  7. (day 1)创建项目--2

    在pycharm查看创建好的项目 可以将myblog当做模块使用

  8. POJ 1200 Crazy Search 字符串的Hash查找

    第一次涉及HASH查找的知识 对于字符串的查找有很多前人开发出来的HASH函数,比较常用的好像是ELF 和 BKDR. 这道题没想到突破点是在于其nc值,告诉你组成字符串的字母种类. 还有用26进制, ...

  9. sqlmap简单流程使用

    -u “(url)” 1.判断可注入的参数 2.判断可以用那种SQL注入技术来注入 3.识别出哪种数据库 4.根据用户选择,读取哪些数据 sqlmap支持五种不同的注入模式: 1.基于布尔的盲注,即可 ...

  10. java实现接口导出csv文件

    Tomxin7 Simple, Interesting | 简单,有趣 业务介绍 项目要求从数据库中查询出相关数据后,通过表格展示给用户,如果用户需要,可以点击导出按钮,导出数据为csv格式. 开发环 ...