树的计数(prufer序列 或 purfer序列)
题解
首先我们要知道一条性质,prufer序列中的某个点出现次数为该点在树中度数-1
感性理解一下,其实按照prufer序列求法自己推一下就出来了
设题目里给的度为$d[]$
先将所有的d--
然后按照排列组合得出来
这是多重集排列数
首先从n-2中选择d[1]个数是$C_{n}^{d[1]}$然后再从剩余n-d[1]中选d[2] $C_{n-d[1]}^{d[2]}$依次类推
$C_{n-2}^{d[1]}\times C_{n-2-d[1]}^{d[2]}\times C_{n-2-d[1]-d[2]}^{d[3]}\times ……\times C_{n-2-d[1]-……-d[n-1]}^{d[n]}$
得到
$\frac{(n-2)!}{\sum\limits_{i=1}^{n}d[i]!}$
高精转移就完了
还是过不了?
一些特判:
首先该题会有无解的情况
然后当只有一个点时方案数为1
然后当出现度数为0的点时方案数要特殊处理
以下是本人丑陋的代码
#include<bits/stdc++.h>
#define ll long long
#define N 10
#define P 1
using namespace std;
ll n,m,d[20000],cnt=0;
bool flag[20000];
struct bignum
{
ll n[200000],l;
bignum(){l=1,memset(n,0,sizeof(n));}
void clear(){while(l>1&&!n[l-1]) l--;}
void print()
{
printf("%lld",n[l-1]);
for(ll i=l-2;i>=0;i--)
printf("%0*lld",P,n[i]);
printf("\n");
}
bignum operator = (ll x)
{
l=0;
while(x)
{
n[l++]=x%N;
x/=N;
}
return *this;
}
bignum operator +(bignum x) const
{
bignum t=*this;
if(x.l>t.l) t.l=x.l;
for(ll i=0;i<t.l;i++)
{
t.n[i]+=x.n[i];
if(t.n[i]>=N)
{
t.n[i+1]+=t.n[i]/N;
t.n[i]%=N;
}
}
return t;
}
bignum operator * (const ll& b)
{
bignum c;
c.l=0;
for(ll i=0,g=0;g||i<l;i++)
{
ll x;
if(i<l)x=n[i]*b+g;
else x=g;
c.n[c.l++]=x%N;
g=x/N;
}
return c;
}
bignum operator *(bignum x) const
{
bignum t=*this,tep;
tep.l=t.l+x.l+1;
for(ll i=0;i<t.l;i++)
for(ll j=0;j<=x.l;j++)
{
tep.n[i+j]+=t.n[i]*x.n[j];
}
for(ll i=0;i<tep.l;i++)
{
tep.n[i+1]+=tep.n[i]/N;
tep.n[i]%=N;
}
tep.clear();
return tep;
}
bool operator <(bignum x) const
{
bignum t=*this,tep;
if(t.l!=x.l) return t.l<x.l;
for(ll i=t.l-1;i>=0;i--)
{
if(t.n[i]!=x.n[i]) return t.n[i]<x.n[i];
}
return 0;
}
bool operator >(bignum x) const
{
bignum t=*this;
if(t.l!=x.l) return t.l>x.l;
for(ll i=t.l-1;i>=0;i--)
{
if(t.n[i]!=x.n[i]) return t.n[i]>x.n[i];
}
return 0;
}
bignum operator -(bignum x) const
{
bignum t=*this;
if(t<x) printf("-"),swap(t,x);
ll jie=0;
for(ll i=0;i<t.l;i++)
{
t.n[i]-=x.n[i];
while(t.n[i]<0)
{
t.n[i]+=N;
jie++;
}
t.n[i+1]-=jie;
jie=0;;
}
t.clear();
return t;
}
bignum operator /(const ll &x)
{
bignum t=*this,r;
ll tmp=0;
r.l=t.l;
for(ll i=t.l-1;i>=0;i--){
tmp+=t.n[i];
if(tmp>=x){
r.n[i]=tmp/x;
tmp%=x;
}
tmp*=N;
}
r.clear();
return r;
}
}ans;
bignum jie(ll x)
{
bignum t;t=1;
for(ll i=2;i<=x;i++){
t=x*i;
}
return t;
}
int main()
{
memset(flag,0,sizeof(flag));
ll sum=0,you0=0;
scanf("%lld",&n);
for(ll i=1;i<=n;i++)
{
scanf("%lld",&d[i]);
if(d[i])flag[i]=1,cnt++;
else you0=1;
d[i]--,sum+=d[i]; }
if(you0&&n==1){
cout<<1<<endl;
return 0;
}
if(sum!=n-2||you0)
{
cout<<0<<endl;
return 0;
}
ans=1;
for(ll i=2;i<=cnt-2;i++)
ans=ans*i;
for(ll i=1;i<=n;i++){
if(flag[i])
for(ll j=2;j<=d[i];j++)
ans=ans/j;
}
ans.print();
}
树的计数(prufer序列 或 purfer序列)的更多相关文章
- 树的计数 + prufer序列与Cayley公式(转载)
原文出处:https://www.cnblogs.com/dirge/p/5503289.html 树的计数 + prufer序列与Cayley公式 学习笔记(转载) 首先是 Martrix67 的博 ...
- 树的计数 + prufer序列与Cayley公式 学习笔记
首先是 Martrix67 的博文:http://www.matrix67.com/blog/archives/682 然后是morejarphone同学的博文:http://blog.csdn.ne ...
- Luogu P2290 [HNOI2004]树的计数 Prufer序列+组合数
最近碰了$prufer$ 序列和组合数..于是老师留了一道题:P2624 [HNOI2008]明明的烦恼 qwq要用高精... 于是我们有了弱化版:P2290 [HNOI2004]树的计数(考一样的可 ...
- 树的计数 Prufer序列+Cayley公式
先安利一发.让我秒懂.. 第一次讲这个是在寒假...然而当时秦神太巨了导致我这个蒟蒻自闭+颓废...早就忘了这个东西了... 结果今天老师留的题中有两道这种的:Luogu P4981 P4430 然后 ...
- [HNOI2004]树的计数 prufer数列
题面: 一个有n个结点的树,设它的结点分别为v1, v2, …, vn,已知第i个结点vi的度数为di,问满足这样的条件的不同的树有多少棵.给定n,d1, d2, …, dn,你的程序需要输出满足d( ...
- bzoj1211: [HNOI2004]树的计数 prufer编码
题目链接 bzoj1211: [HNOI2004]树的计数 题解 prufer序 可重排列计数 代码 #include<bits/stdc++.h> using namespace std ...
- BZOJ 1211 HNOI2004 树的计数 Prufer序列
题目大意:给定一棵树中全部点的度数,求有多少种可能的树 Prufer序列.详细參考[HNOI2008]明明的烦恼 直接乘会爆long long,所以先把每一个数分解质因数.把质因数的次数相加相减.然后 ...
- 【BZOJ1005/1211】[HNOI2008]明明的烦恼/[HNOI2004]树的计数 Prufer序列+高精度
[BZOJ1005][HNOI2008]明明的烦恼 Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可 ...
- 【BZOJ1211】【HNOI2004】树的计数 prufer序列
题目描述 给你\(n\)和\(n\)个点的度数,问你有多少个满足度数要求的生成树. 无解输出\(0\).保证答案不超过\({10}^{17}\). \(n\leq 150\) 题解 考虑prufer序 ...
随机推荐
- MySQL从库维护经验分享
前言: MySQL 主从架构应该是最常用的一组架构了.从库会实时同步主库传输来的数据,一般从库可以作为备用节点或作查询使用.其实不只是主库需要多关注,从库有时候也要经常维护,本篇文章将会分享几点从库维 ...
- 再谈vbo
我们之前都是通过glNamedBufferData初始化buffer object,初始化的意思是为buffer object开辟显存空间,并填充数据: GLfloat position[] = { ...
- spring-第三章-jdbc
一,回顾 aop:面向切面编程,就是将一些和主业务流程没有关系的公共代码,提取封装到切面类,通过切入点规则,可以对目标方法进行功能增强;也就是可以再目标方法执行的前后添加一段额外逻辑代码; 二,Jdb ...
- ES6对象的新增方法的使用
Object.assign Object Object.assign(target, ...sources) 将所有可枚举属性的值从一个或多个源对象复制到目标对象 参数: target 目标对象 so ...
- 搞清楚 硬件环境 os环境 网络环境 搞清楚测试工具 测试步骤 自己搭测试环境 自测
1,遇事的第一反应要从变化情绪转变为做出判断.判断什么?判断这一件事对自己是否重要,是否关乎我的个人利益,是否影响我的人际关系等等等等.如果答案都是否,那就没必要着急忙慌了.如果答案是是 冷静,其实是 ...
- Zabbix 自动发现并监控磁盘IO、报警 引言
引言 Zabbix并没有提供模板来监控磁盘的IO性能,所以我们需要自己来创建一个,由于一台服务器中磁盘众多,如果只有一两台可以手动添加,但服务集群达到几十那就非常麻烦,因此需要利用自动发现这个功能,自 ...
- gpcj-07.为什么是连锁零售类公司
1.量化分析的真面目 本课的目的: ·理解零售类公司价值分析的逻辑·学会量化分析公司的思路和原理前言的前沿 和大部分投资者不同,我们的投资核心之一,就是从下而上的分析.宏观经济对我们公司分析影响极少. ...
- java 文件上传下载
翻新十年前的老项目,文件上传改为调用接口方式,记录一下子~~~ java后台代码: //取配置文件中的上传目录 @Value("${uploadPath}") String pat ...
- Deploying Portainer CE in Docker
Portainer是一个轻量级的管理UI,它允许你轻松地管理你的Docker和Kubernetes集群 https://documentation.portainer.io/v2.0/deploy/c ...
- object_pool对象池
object_pool对象池 object_pool是用于类实例(对象)的内存池,它能够在析构时调用所有已经分配的内存块调用析构函数,从而正确释放资源,需要包含以下头文件: #include < ...