Codeforces 1109D. Sasha and Interesting Fact from Graph Theory 排列组合,Prufer编码
原文链接https://www.cnblogs.com/zhouzhendong/p/CF1109D.html
题意
所有边权都是 [1,m] 中的整数的所有 n 个点的树中,点 a 到点 b 的距离恰好是 m 的有几个。
$$n,m\leq 10^6$$
题解
首先显然 a 和 b 的具体值是没用的。
于是我们就可以直接计数:
枚举树链 ab 上除了 a 和 b 有几个节点,假设是 i 个节点,那么这种情况下的方案总数是多少?
首先,ab 路径上 i+1 条 [1,m] 的边的和是 m ,共有 $\binom{m-1}{i}$ 种边权的取值;
然后,ab 路径上共有 i 个点,方案数是从剩下的 n-2 个点种选出 i 个并排列,即 $\binom{n-2}i i!$ 。
然后,剩下的 n-2-i 条边每条都有 m 种取值,方案数是 $m^{n-2-i}$ 。
最后,考虑生成树的个数,用 prufer 序列的结论推一推就可以知道方案数是 $n^{n-3-i}(i+2)$ 。
所以答案是
$$\sum_{i=0}^{n-2} \binom{n-2}{i}\binom{m-1}{i}m^{n-2-i}n^{n-3-i}i!(i+2)$$
UPD(2019-03-04): 更新一下关于那个 prufer 编码推出的公式的证明:
prufer 编码有几个性质:
1. 假如是 n 个点,那么编码长度为 n-2 ,且每一个位置可以放 1~n 之间的任意数,每一个 prufer 编码与每一个树一一对应。
2. 假设树中一个点 x 的度是 d[x] ,那么在对应的 prufer 编码中,x 出现 d[x]-1 次。
假设我们有 n 个点,被分成了 k 个点集,每个点集里的点已经连通,不同点集之间的点两两无边,现在我们要在这个 n 个点 n-k 条边的基础上求生成树个数。设第 i 个点集包含的点数为 size[i] 。
那么,如果我们把这 k 个点集每一个点都看作一个点,做一个 k 个点的生成树,那么有 $k^{k-2}$ 种方案;但是由于这里的每一个点都是一个点集,所以假设它是点集 i,那么从他连出去的每一条边的属于集合i的端点,都有 size[i] 种选法。也就是说,对于一个 k 个点的 prufer 编码,假设在这个编码中,数字 i 出现了 c[i] 次,那么这个编码对应到原树上就会贡献 $\prod_{i=1}^k size[i] ^ {c[i]+1} $ 次。
我们把每一个 "c[i]+1" 中多出来的 1 提出,看作常量,我们来对于所有 prufer 编码求贡献总和:
$$\sum_{P是一个prufer编码}\ \ \ \ \ \prod_{i=1}^k size[i] ^ {c[i]}$$ 。
考虑到这个prufer编码的每一位选择第 i 个点集,就会对乘积有 $size[i]$ 的贡献,根据乘法分配律,我们可以得到上面的那个式子就是: $(\sum_{i=1}^k size[i])^{k-2} = n ^ {k-2}$ 。
再乘上之前提出的东西,所以答案就是:
$$(\sum_{i=1}^k size[i])^{k-2} \cdot \prod_{i=1}^k size[i] $$
本题要求的那个,只是这个模型的弱化版。至此已经可以解决这个问题了。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL read(){
LL x=0,f=0;
char ch=getchar();
while (!isdigit(ch))
f|=ch=='-',ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
const int N=1000005,mod=1e9+7;
int n,m,a,b;
int Fac[N],Inv[N];
int C(int n,int m){
if (m>n||m<0)
return 0;
return (LL)Fac[n]*Inv[m]%mod*Inv[n-m]%mod;
}
int Pow(int x,int y){
if (y<0)
return Pow(x,y+mod-1);
int ans=1;
for (;y;y>>=1,x=(LL)x*x%mod)
if (y&1)
ans=(LL)ans*x%mod;
return ans;
}
void init(int n){
for (int i=Fac[0]=1;i<=n;i++)
Fac[i]=(LL)Fac[i-1]*i%mod;
Inv[n]=Pow(Fac[n],mod-2);
for (int i=n;i>=1;i--)
Inv[i-1]=(LL)Inv[i]*i%mod;
}
void Add(int &x,int y){
if ((x+=y)>=mod)
x-=mod;
}
int main(){
n=read(),m=read(),a=read(),b=read();
init(max(n,m));
int ans=0;
for (int i=0;i<=n-2;i++)
Add(ans,(LL)C(n-2,i)*C(m-1,i)%mod*Fac[i]%mod
*Pow(m,n-2-i)%mod*Pow(n,n-3-i)%mod*(i+2)%mod);
cout<<ans<<endl;
return 0;
}
Codeforces 1109D. Sasha and Interesting Fact from Graph Theory 排列组合,Prufer编码的更多相关文章
- Codeforces 1109D. Sasha and Interesting Fact from Graph Theory
Codeforces 1109D. Sasha and Interesting Fact from Graph Theory 解题思路: 这题我根本不会做,是周指导带飞我. 首先对于当前已经有 \(m ...
- Codeforces 1109D Sasha and Interesting Fact from Graph Theory (看题解) 组合数学
Sasha and Interesting Fact from Graph Theory n 个 点形成 m 个有标号森林的方案数为 F(n, m) = m * n ^ {n - 1 - m} 然后就 ...
- CF1109D Sasha and Interesting Fact from Graph Theory
CF1109D Sasha and Interesting Fact from Graph Theory 这个 \(D\) 题比赛切掉的人基本上是 \(C\) 题的 \(5,6\) 倍...果然数学计 ...
- Sasha and Interesting Fact from Graph Theory CodeForces - 1109D (图论,计数,Caylay定理)
大意: 求a->b最短路长度为m的n节点树的个数, 边权全部不超过m 枚举$a$与$b$之间的边数, 再由拓展$Caylay$定理分配其余结点 拓展$Caylay$定理 $n$个有标号节点生成k ...
- Codeforces1113F. Sasha and Interesting Fact from Graph Theory(组合数学 计数 广义Cayley定理)
题目链接:传送门 思路: 计数.树的结构和边权的计数可以分开讨论. ①假设从a到b的路径上有e条边,那么路径上就有e-1个点.构造这条路径上的点有$A_{n-2}^{e-1}$种方案: ②这条路径的权 ...
- CF1109DSasha and Interesting Fact from Graph Theory(数数)
题面 传送门 前置芝士 Prufer codes与Generalized Cayley's Formula 题解 不行了脑子已经咕咕了连这么简单的数数题都不会了-- 首先这两个特殊点到底是啥并没有影响 ...
- Codeforces Round #485 (Div. 2) F. AND Graph
Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...
- Codeforces 703D Mishka and Interesting sum 离线+树状数组
链接 Codeforces 703D Mishka and Interesting sum 题意 求区间内数字出现次数为偶数的数的异或和 思路 区间内直接异或的话得到的是出现次数为奇数的异或和,要得到 ...
- CodeForces 840B - Leha and another game about graph | Codeforces Round #429(Div 1)
思路来自这里,重点大概是想到建树和无解情况,然后就变成树形DP了- - /* CodeForces 840B - Leha and another game about graph [ 增量构造,树上 ...
随机推荐
- shutil模块和几种文件上传Demo
一.shutil模块 1.介绍 shutil模块是对os中文件操作的补充.--移动 复制 打包 压缩 解压 2.基本使用 1. shutil.copyfileobj(文件1, 文件2, 长度) 将文件 ...
- 【XSY3139】预言家 数位DP NFA
题目描述 有一个定义在 \(\{0,1,2,3,4,5,6,7,8,9\}\) 上的合规表达式,包含三种基本的操作: 结合:\(E_1E_2\) 分配:\((E_1|E_2|\ldots|E_n),n ...
- 4.1 socket
socket 背景概念 脑图结构 OSI 模型 socket 概念特性 脑图结构 理解示意图 额外补充 Socket是应用层与 TCP/IP协议族通信的中间软件抽象层,它是一组接口. 在设计模式中 ...
- 越光后端开发——ygapi(3.引入xadmin)
1.引入xadmin 1.将xadmin文件夹放入extra_apps目录下: 2.在每个app下新建adminx.py 1.apps/users/目录下新建adminx.py: import xad ...
- 金融量化分析【day112】:量化平台的使用-初始化函数
一.set_benchmark - 设置基准 1.实现代码 # 导入函数库 import jqdata #初始化函数,设定基准等等 def initialize(context): set_bench ...
- Ubuntu设置和查看环境变量
设置环境变量的三种方法 1.1 临时设置 export PATH=/home/yan/share/usr/local/arm/3.4.1/bin:$PATH 1.2 当前用户的全局设置 打开~/.ba ...
- Chrome 禁止从页面打开 Data URI 网址了
现如今,网民的网络账户被盗,很有可能是被“钓鱼”了.去年的一份安全报告中指出:“近85%的资金损失是通过钓鱼网址泄露支付信息造成的”. 传统的钓鱼网站通常是申请一个和被冒充网站相似的域名,比如 tao ...
- NightWatch端到端测试
NightWatch http://nightwatchjs.org/ Nightwatch.js Browser automated testing done easy. Write End-to- ...
- H5——弹性盒
[flex 弹性盒布局] * 1.给父容器添加display:flex/inline-flex;属性 * 2.父容器可以使用的属性值有: * ① flex-direction 属性决定主轴的方向(即项 ...
- Mysql中设置指定IP的特定用户及特定权限
创建用户:格式:grant select on 数据库.* to 用户名@登录主机 identified by '密码' 举例: 例 1:增加一个用户 test1 密码为 abc,让他可以在任何主机上 ...