题面

有n个点,它们从1到n进行标号,第i个点的限制为度数不能超过A[i].

现在对于每个s (1 <= s <= n),问从这n个点中选出一些点组成大小为s的有标号无根树的方案数。

100%的数据:n <= 100

100

prufer序列

每个大小为n,有标号无根树都可以表示成一个长度为(n-2)且取值在[1,n]的序列。

这个序列就叫prufer序列

树转prufer序列

1.每次查找一个标号最小且度数为一的点,使与之相连的点的编号加入序列尾;

2.删除树中的这个点。

prufer序列转树

1.新建一个包含[1,n]的集合;

2.找出集合中在序列中未出现的最小编号,并使之与序列头连一条边;

3.删除集合中的这个编号,以及序列头;

4.重复2-3步骤n-2次,序列则为空;

5.把集合中的剩余两个编号相连,原树复原。

性质

1.长度为(n-2)的prufer序列的集合与大小为n的带标号无根树的集合一一映射。

2.带标号无根树的任意点的度数等于,与之对应的prufer序列的对应编号出现次数+1。


Back to Problem

Pre

假设我们求出了一个prufer序列的长度\(n\),并且知道其中每个编号出现的次数\(c_i\)。

由性质2,那么这种prufer序列的贡献就是,它的不同全排列数,有:

\[Ans=n!*\sum_{i=1}^n\frac{1}{c_i!}
\]

正文

所以我们把原题转化为在序列上的动态规划

设\(f_{i,j,k}\)表示前i个点,用了j个点,序列长度为k的方案数。

那么就有,

\[f_{i,j,k} \Rightarrow \begin{cases}
f_{i+1,j,k}\\
f_{i+1,j+1,k+l},&l \in [0,a_i-1]
\end{cases}
\]

最终答案就是\(f_{n,s,s-2}*(s-2)!\)。

时间复杂度为\(O(n^4)\),但由于冗余状态的存在,是能卡过的。

原题是要用FFT优化到\(O(n^3*log_n)\)

Code

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define ll long long
#define fo(i,x,y) for(int i=x;i<=y;i++)
#define fd(i,x,y) for(int i=x;i>=y;i--)
using namespace std;
const char* fin="tree.in";
const char* fout="tree.out";
const int inf=0x7fffffff;
const int maxn=107,mo=1004535809;
int n,a[maxn],f[maxn][maxn][maxn],fact[maxn],nf[maxn];
int qpower(int a,int b){
int c=1;
while (b){
if (b&1) c=1LL*a*c%mo;
a=1LL*a*a%mo;
b>>=1;
}
return c;
}
int ni(int v){return qpower(v,mo-2);}
int main(){
freopen(fin,"r",stdin);
freopen(fout,"w",stdout);
scanf("%d",&n);
fact[0]=1;
fo(i,1,maxn-1) fact[i]=1LL*fact[i-1]*i%mo;
fo(i,0,maxn-1) nf[i]=ni(fact[i]);
fo(i,1,n) scanf("%d",&a[i]);
memset(f,0,sizeof f);
f[1][0][0]=1;
fo(i,1,n)
fo(j,0,i-1)
fo(k,0,n){
f[i+1][j][k]=(f[i][j][k]+f[i+1][j][k])%mo;
fo(l,0,a[i]-1){
if (k+l>n) break;
f[i+1][j+1][k+l]=(f[i+1][j+1][k+l]+1LL*f[i][j][k]*nf[l])%mo;
}
}
printf("%d ",n);
fo(i,2,n) cout<<1LL*f[n+1][i][i-2]*fact[i-2]%mo<<" ";
return 0;
}

【JZOJ5068】【GDSOI2017第二轮模拟】树 动态规划+prufer序列的更多相关文章

  1. 【JZOJ5071】【GDSOI2017第二轮模拟】奶酪 树形dp

    题面 CJY很喜欢吃奶酪,于是YJC弄到了一些奶酪,现在YJC决定和CJY分享奶酪. YJC弄到了n-1块奶酪,于是他把奶酪挂在了一棵n个结点的树上,每根树枝上挂一块奶酪,每块奶酪都有重量. YJC和 ...

  2. 【JZOJ5060】【GDOI2017第二轮模拟day1】公路建设 线段树+最小生成树

    题面 在Byteland一共有n 个城市,编号依次为1 到n,它们之间计划修建m条双向道路,其中修建第i 条道路的费用为ci. Byteasar作为Byteland 公路建设项目的总工程师,他决定选定 ...

  3. [jzoj5073 GDOI2017第二轮模拟] 影魔

    Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个灵 ...

  4. 【JZOJ5064】【GDOI2017第二轮模拟day2】友好城市 Kosarajo算法+bitset+ST表+分块

    题面 在Byteland 一共有n 座城市,编号依次为1 到n,这些城市之间通过m 条单向公路连接. 对于两座不同的城市a 和b,如果a 能通过这些单向道路直接或间接到达b,且b 也能如此到达a,那么 ...

  5. GDOI2017第二轮模拟day1 总结

    平民比赛 这场比赛的暴力分非常友好. 但是我并没有拿到全部的暴力分. 1(暴力分\(60/100\)) 暂时我可以拿的暴力分为\(30/100\),直接mst模拟即可. 然而当时打了个辣鸡莫队,结果爆 ...

  6. bzoj 1005: [HNOI2008]明明的烦恼 树的prufer序列+万进制

    题目传送门 思路: 这道题需要前置知识prufer编码,这篇博客对prufer编码和这道题的分析写的很好. 这里主要讲一些对大数阶乘的分解,一个办法当然是用高精度,上面这篇博客用的是java,还有一个 ...

  7. 树的Prufer 编码和最小生成树计数

      Prufer数列 Prufer数列是无根树的一种数列.在组合数学中,Prufer数列由有一个对于顶点标过号的树转化来的数列,点数为n的树转化来的Prufer数列长度为n-2.它可以通过简单的迭代方 ...

  8. 【BZOJ 1211】 1211: [HNOI2004]树的计数 (prufer序列、计数)

    1211: [HNOI2004]树的计数 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2468  Solved: 868 Description 一 ...

  9. bzoj1211: [HNOI2004]树的计数(prufer序列+组合数学)

    1211: [HNOI2004]树的计数 题目:传送门 题解: 今天刚学prufer序列,先打几道简单题 首先我们知道prufer序列和一颗无根树是一一对应的,那么对于任意一个节点,假设这个节点的度数 ...

随机推荐

  1. collections中namedtuple的用法

    我们知道tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成: p = (1, 2) 但是,看到(1, 2),很难看出这个tuple是用来表示一个坐标的.这时,namedtuple就派上了用 ...

  2. Mount- Linux必学的60个命令

    1.作用 mount命令的作用是加载文件系统,它的用权限是超级用户或/etc/fstab中允许的使用者. 2.格式 mount -a [-fv] [-t vfstype] [-n] [-rw] [-F ...

  3. Mahout In Action-第一章:初识Mahout

    1. 初识Mahout 本章涵盖以下内容: Apache Mahout是什么? 现实中推荐系统引擎.聚类.分类概述 配置mahout 读者可能从本书的标题中猜测到,本书是一本讲解如何将mahout应用 ...

  4. JZOJ[5971]【北大2019冬令营模拟12.1】 party(1s,256MB)

    题目 题目大意 给你一棵树,在树上的某一些节点上面有人,要用最小的步数和,使得这些人靠在一起.所谓靠在一起,即是任意两个人之间的路径上没有空的节点(也就是连在一起). N≤200N \leq 200N ...

  5. 【HTML5】如何处理HTML5新标签的浏览器兼容版问题

    HTML5规范毕竟是刚刚才定义完成的规范,还有一些浏览器并不能支持其中的新标签和新属性,尤其是IE8及以下版本浏览器.以下介绍一些在页面中使用HTML5新标签的实践方法,目的是让HTML5中的新标签在 ...

  6. UITableViewHeaderFooterView can't change custom background when loading from nib

    down voteforite I've created a custom UITableViewHeaderFooterView and successfully load from nib int ...

  7. python 日记 day1

    1.python2 与 python3 的区别:   a. python2 源码不标准,混乱,重复代码太多.默认方式是ascii码,解决方式:#-*- encoding:utf-8 -*-   b. ...

  8. 深入浅出 Java Concurrency (8): 锁机制 part 3[转]

    接上篇,这篇从Lock.lock/unlock开始.特别说明在没有特殊情况下所有程序.API.文档都是基于JDK 6.0的. public void java.util.concurrent.lock ...

  9. 禁用 ipv6

    # 禁用整个系统所有接口的IPv6 net.ipv6.conf.all.disable_ipv6 = # 禁用某一个指定接口的IPv6(例如:eth0, lo) net.ipv6.conf.lo.di ...

  10. jeecms 链接标签

    .引入页面 [#include "../include/header-site.html"/]12.导航栏只有前两个带链接 [#if c_index<2] href=&quo ...