题解

首先我们要知道一条性质,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();
}

最新文章

  1. Storm介绍(二)
  2. HDU 1026 Ignatius and the Princess I(带路径的BFS)
  3. 个推,手机推送api的使用
  4. Java开源GIS系统
  5. 6、网页制作Dreamweaver(HTML结构--dom操作)
  6. HDU 5965 Gym Class 贪心+toposort
  7. iOS单例的两种实现
  8. 安装 vsftp
  9. Redhat下安装fedora
  10. markdown 常用格式API
  11. Python beautifulsoup 选择器 select 选择&lt;meta/&gt;等不需要成对结尾标签未写‘/’
  12. 使用Ajax发送http请求(get&amp;post请求)
  13. [UVAlive4297]First Knight
  14. Aptana下Django1.6以后的项目模板结构改造
  15. C#8.0可空引用类型的使用注意要点
  16. dbexpress连接mysql提示Operation not allowed on a unidirectional dataset
  17. Android文档-开发者指南-第一部分:入门-中英文对照版
  18. 【PPT】 Least squares temporal difference learning
  19. Dynamic dispatch
  20. Linux free -m 详解命令

热门文章

  1. Nebula Graph 的 Ansible 实践
  2. TLB和CPU缓存
  3. base64stego 还不懂base64的隐写,详解15行代码带你领略
  4. 不同规模的企业对CRM的需求是否相同?
  5. 24.Qt Quick QML-Canvas和Context2D详解
  6. [Java] 数据分析--统计
  7. Linux中级之ansible概念及hoc命令行调用模式
  8. 校准仪开发日志--2017-10-20 today&#39;s question
  9. Java 将Excel转为SVG的方法
  10. Qt 进度条