51nod 1806 wangyurzee的树
可是wangyurzee发现方案数太多了,于是他又给出了m个限制条件,其中第i个限制条件限制了编号为u[i]的节点的度数不能为d[i]。
一个节点的度数,就是指和该节点相关联的边的条数。
这样一来,方案数就减少了,问题也就变得容易了,现在请你告诉wangyurzee连边的方案总数为多少。
答案请对1000000007取模。
总方案共有3种,分别为{(1,2),(1,3)},{(1,2),(2,3)},{(2,3),(1,3)}。其中第二种方案节点1的度数为2,不符合要求,因此答案为2。
第一行输入2个整数n(1<=n<=1000000),m(0<=m<=17)分别表示节点个数以及限制个数。
第2行到第m+1行描述m个限制条件,第i+1行为2个整数u[i],d[i],表示编号为u[i]的节点度数不能为d[i]。
为了方便起见,保证1<=ui<=m。同时保证1<=ui<=n,1<=di<=n-1,保证不会有两条完全相同的限制。
输出一行一个整数表示答案。
3 1
1 2
2
树 prufer编码 数学问题 容斥
算度数不为d[i]的方案数看上去不可做,考虑算度数为d[i]的方案数。
首先我们知道n个点有标号生成树的数量为 $ n^{n-2} $
注意到限制条件m很小,可以计算不满足一个条件的方案数,不满足两个条件的方案数,不满足三个条件的方案数……然后容斥一下。
假设当前计算不满足某x个条件的方案数:
若一个点的度数为 $ d[i] $,那么它在prufer序列中出现了 $ d[i]-1 $次。
现在有x个点的贡献确定了,其度数总和为
$ \sum_{i=1}^{x} d[i] $
那么在prufer序列中有
$ sum=\sum_{i=1}^{x} (d[i]-1) $ 个位置被占用。
占用这么多位置的方案数是
$ C(n-2, sum)$
这些位置里选$d[1]-1$个位置填第1种编号,方案数为
$ C(sum,d[1]-1)$
再选位置填第2种编号,方案数为
$ C(sum-d[1]-1,d[2]-1)$
以此类推
根据乘法原理把上面这些组合数乘起来,化简得到:
$ \frac{(n-2)!}{(n-2-sum)! * \Pi (d[i]-1)!}$
prufer序列中剩下的位置可以任意填不被限制度数的点,共有
$(n-x)^{n-2-sum}$ 种方案
所以符合当前度数限制的方案数有
$ \frac{(n-2)!}{(n-2-sum)! * \Pi (d[i]-1)!} * (n-x)^{n-2-sum}$
注意:可能出现两个限制条件同时限制一个点的度数,需要特判
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
using namespace std;
const int mod=1e9+;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int inv[mxn],fac[mxn];
void init(int n){
n+=;
inv[]=inv[]=;fac[]=fac[]=;
for(int i=;i<=n;i++){
fac[i]=(LL)fac[i-]*i%mod;
inv[i]=((-mod/i*(LL)inv[mod%i])%mod+mod)%mod;
}
for(int i=;i<=n;i++)inv[i]=(LL)inv[i-]*inv[i]%mod;
return;
}
int n,m;
int u[],d[];bool vis[];
LL ans=;
int ksm(int a,int k){
int res=;
while(k){
if(k&)res=(LL)res*a%mod;
a=(LL)a*a%mod;
k>>=;
}
return res;
}
int main(){
int i,j;
n=read();m=read();
if(n==){printf("1\n");return ;}
init(n);
for(i=;i<m;i++){
u[i]=read();d[i]=read();
}
ans=ksm(n,n-);
int ed=<<m;
for(int S=;S<ed;S++){//枚举状态
int tmp=S,smm=,cnt=;bool flag=;
LL down=;
memset(vis,,sizeof vis);
for(i=;i<m;i++){
if((S>>i)&){
if(vis[u[i]]){flag=;break;}//限制重复
vis[u[i]]=;
smm+=d[i]-;
++cnt;
down=down*inv[d[i]-]%mod;
}
}
if(!flag)continue;
if(smm>n-)continue;
LL up=fac[n-];
up=up*down%mod*inv[n--smm]%mod;
up=up*ksm(n-cnt,n--smm)%mod;
(ans+=(cnt&)?-up:up)%=mod;
}
ans=(ans+mod)%mod;
printf("%lld\n",ans);
return ;
}
51nod 1806 wangyurzee的树的更多相关文章
- 【题解】51nod 1806 wangyurzee的树
看这道题目懵逼了好久, \(m <= 17\) 一眼容斥,然而并没有想到怎么求出生成树的个数.然后灵光一闪——我不是学过一个叫Prüfer编码的东西嘛?!那就完美解决啦~ Prüfer编码就是将 ...
- 51nod 1443 路径和树(最短路)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1443 1443 路径和树 题目来源: CodeForces ...
- 51nod 1681 公共祖先 | 树状数组
51nod 1681 公共祖先 有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另一个未知的平行宇宙,这n人的祖辈关系仍然是树形结构,但他们相互之间的关系却完 ...
- 51Nod 1737 配对(树的重心)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1737 题意: 思路: 树的重心. 树的重心就是其所以子树的最大的子树结点 ...
- 51nod 1272 思维/线段树
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1272 1272 最大距离 题目来源: Codility 基准时间限制:1 ...
- 51Nod 1443 路径和树 —— dijkstra
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1443 首先要得到一个最短路树: 注意边权和最小,因为在最短路中,每 ...
- 51nod 1443 路径和树(最短路树)
题目链接:路径和树 题意:给定无向带权连通图,求从u开始边权和最小的最短路树,输出最小边权和. 题解:构造出最短路树,把存留下来的边权全部加起来.(跑dijkstra的时候松弛加上$ < $变成 ...
- 51Nod 1443 路径和树
还是一道很简单的基础题,就是一个最短路径树的类型题目 我们首先可以发现这棵树必定满足从1出发到其它点的距离都是原图中的最短路 换句话说,这棵树上的每一条边都是原图从1出发到其它点的最短路上的边 那么直 ...
- 51Nod 1680 区间求和 树状数组
题意: 给出一个长度为\(n\)的数列\(A_i\),定义\(f(k)\)为所有长度大于等于\(k\)的子区间中前\(k\)大数之和的和. 求\(\sum_{k=1}^{n}f(k) \; mod \ ...
随机推荐
- Windows SDK 非模态对话框的消息处理
在SDK中使用非模态对话框时的几个问题: 1.为什么要调用IsDialogMessage?? 2.非模态对话框与主窗口有什么区别? 3.如果不调用IsDialogMessage,消息能不能传递到对话框 ...
- iOS开发UIApplication用法
1.简单介绍 (1)UIApplication对象是应用程序的象征,一个UIApplication对象就代表一个应用程序. (2)每一个应用都有自己的UIApplication对象,而且是单例的,如果 ...
- 在线api查询网站
1.包含各种常用的语言 http://tool.oschina.net/apidocs
- C#中pictureBox笔记
if (File.Exists(productInfo.预览图路径)) this.picPreview.Image = BitmapFactory.Alloc(productInfo.预览图路径, f ...
- stm32f4xx标准外设固件库
STM32F4的相关资料:http://www.stmcu.org/document/list/index/category-523 一.标准固件库简介 本文下载的是STM32F4xx_DSP_Std ...
- Android Shimmer 发光微光动画
这是Facebook提供的一个类库(题外话http://code.facebook.com,这里有很多好玩有趣有用的Facebook开源的类库) 这么炫酷的发光动画效果,想必很多Android码农都会 ...
- 前端基础:HTML标签(下)
前端基础HTML标签(下) 1.表单 表单的功能主要用于向服务器传输数据,从而实现客户端与Web服务器的交互.表单能够包含input系列标签,比如:文本字段.复选框.单选按钮.提交按钮等:表单还包含t ...
- Atom Editor 插件 atom-less 的使用方法
一.下载安装 atom-less atom-less 项目在这里:https://github.com/schmuli/atom-less 安装方法请参考这篇博文:http://blog.csdn.n ...
- 协程简介-异步IO
协程 1. 协程,又称微线程,纤程.协程是用户自己控制的,CPU根本不知道协程的存在,CPU只认识线程. 2. 线程切换的时候,会保存在CPU的寄存器里面. 协程切换的时候,却都是由用户自己的实现的. ...
- [洛谷P3931]SAC E#1 - 一道难题 Tree
题目大意:给你一棵带权有根树,可以切断一些边,问使得根和叶子节点不连通的最小代价. 题解:做了一天的网络流,这道题显然可以用最小割来做,但是也可以用树形$DP$,基本同[SDOI2011]消耗战,这道 ...