树的计数(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序 ...
随机推荐
- ConcurrentHashMap源码解读一
最近在学习并发map的源码,如果由错误欢迎指出.这仅供我自己学习记录使用. 首先就先来说一下几个全局变量 private static final int MAXIMUM_CAPACITY = 1 & ...
- [bug] idea编译后没有xml文件
原因 在maven中build 参考 https://www.cnblogs.com/lewskay/p/6422464.html https://blog.csdn.net/lovequanquqn ...
- gparted 当分区空间大于1T 用gparted分区
lsblkfdisk -lparted -s /dev/sdb mklabel msdos parted -s /dev/sdb mkpart primary 0 100%lsblk dfparted ...
- python类传参示例
1 class f(): 2 3 def __init__(self, *args, **kwargs): 4 print('args Is', args) # args Is ('5', 'fff' ...
- Centos6下通过 oprofile分析CPU性能
Centos6下通过 oprofile分析CPU性能 2014-01-18 10:55:15 bobpen 阅读数 2218更多 分类专栏: linux 版权声明:本文为博主原创文章,遵循CC 4 ...
- 11.10 chkconfig:管理开机服务
chkconfig 命令是Redhat系列的Linux系统中的系统服务管理工具,它可以用于查询和更新不同的运行等级下系统服务的启动状态. chkconfig命令的参数选项及说明 --list 显 ...
- mysql数据库-日志管理
MySQL 支持丰富的日志类型 事务日志:transaction log 事务日志的写入类型为"追加",因此其操作为"顺序IO":通常也被称为:预写式日志 wr ...
- vue相关面试知识点总结
vue v-for循环中为什么要用key?为什么index不能作为key? key 的特殊 attribute 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes.如 ...
- [leetcode] 38. 报数(Java)(字符串处理)
38. 报数 水题 class Solution { public String next(String num) { String ans = ""; int i = 0; wh ...
- TPS和响应时间之间是什么关系
在这个图中,定义了三条曲线.三个区域.两个点以及三个状态描述. 三条曲线:吞吐量的曲线(紫色).使用率 / 用户数曲线(绿色).响应时间曲线(深蓝色).三个区域:轻负载区(Light Load).重负 ...