题解 洛谷 P4492 【[HAOI2018]苹果树】
考虑生成一颗二叉树的过程,加入第一个节点方案数为\(1\),加入第二个节点方案数为\(2\),加入第三个节点方案数为\(3\),发现生成一颗\(n\)个节点的二叉树的方案数为\(n!\)。
所以题目中所求即为点与点之间的距离之和,考虑每一条边的贡献,即\(\sum\limits_esize_x \times size_y\),\(x\)和\(y\)为这条边的两个端点。
可以枚举每一个节点\(i\),再枚举节点\(i\)子树大小\(j\),其和父亲的连边对答案的贡献为\(j(n-j)\),然后贡献再乘上这个状态对应的方案数,就是所求的答案,因此问题转化为了求节点\(i\)子树大小为\(j\)的方案数。
可以把计算方案数看作三部分,安排点\(i\)子树中点的方案数,安排比\(i\)编号小的点的方案数,安排比\(i+j-1\)编号大的点的方案数。
考虑点\(i\)子树为一颗大小为\(j\)的二叉树,生成这个子树的方案数为\(j!\)。其中的点是有编号的,并且编号都比\(i\)大,所以安排子树中的点方案数还要考虑选出哪些点,总方案数即为\(j!\binom{n-i}{j-1}\)。
比点\(i\)编号小的点的安排方案数即为生成一颗\(i\)个点的二叉树的方案数,即\(i!\)。
比点\(i\)编号大的点在安排时都不能放到\(i\)的子树中。考虑安排好\(i\)子树内所有点后,即安排好前\(i+j-1\)个点后,再新加入一个点的方案数为\(i-1\),加入第二点的方案数为\(i\),加入第二点的方案数为\(i+1\),一直加到最后一个点,加入最后一个点的方案数为\(n-j-1\),总方案数即为\(\frac{(n-j-1)!}{(i-2)!}\)。
把边的贡献和上面得出的方案数乘起来,即为答案,得:
\]
考虑模数可能没有逆元,所以将式子进一步化简,去掉除法,得:
\]
然后预处理阶乘和组合数,\(n^2\)计算即可。
\(code:\)
#include<bits/stdc++.h>
#define maxn 2010
using namespace std;
typedef long long ll;
template<typename T> inline void read(T &x)
{
x=0;char c=getchar();bool flag=false;
while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
if(flag)x=-x;
}
ll n,p,ans;
ll f[maxn],C[maxn][maxn];
void init()
{
f[0]=1;
for(int i=1;i<=n;++i) f[i]=f[i-1]*i%p;
for(int i=0;i<=n;++i) C[i][0]=1;
for(int i=1;i<=n;++i)
for(int j=1;j<=i;++j)
C[i][j]=(C[i-1][j-1]+C[i-1][j])%p;
}
int main()
{
read(n),read(p),init();
for(int i=1;i<=n;++i)
for(int j=1;j<=n-i+1;++j)
ans=(ans+j*(n-j)%p*f[j]%p*C[n-i][j-1]%p*f[n-j-1]%p*i%p*(i-1)%p)%p;
printf("%lld",ans);
return 0;
}
题解 洛谷 P4492 【[HAOI2018]苹果树】的更多相关文章
- [洛谷P4492] [HAOI2018]苹果树
洛谷题目链接:[HAOI2018]苹果树 题目背景 HAOI2018 Round2 第一题 题目描述 小 C 在自己家的花园里种了一棵苹果树, 树上每个结点都有恰好两个分支. 经过细心的观察, 小 C ...
- 洛谷P4492 [HAOI2018]苹果树(组合数)
题意 题目链接 Sol 有点自闭,.我好像对组合数一窍不通(~~~~) Orz shadowice // luogu-judger-enable-o2 #include<bits/stdc++. ...
- [洛谷P4491] [HAOI2018]染色
洛谷题目链接:[HAOI2018]染色 题目背景 HAOI2018 Round2 第二题 题目描述 为了报答小 C 的苹果, 小 G 打算送给热爱美术的小 C 一块画布, 这块画布可 以抽象为一个长度 ...
- 题解 洛谷P5018【对称二叉树】(noip2018T4)
\(noip2018\) \(T4\)题解 其实呢,我是觉得这题比\(T3\)水到不知道哪里去了 毕竟我比较菜,不大会\(dp\) 好了开始讲正事 这题其实考察的其实就是选手对D(大)F(法)S(师) ...
- 题解 洛谷 P3396 【哈希冲突】(根号分治)
根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...
- 题解-洛谷P5410 【模板】扩展 KMP(Z 函数)
题面 洛谷P5410 [模板]扩展 KMP(Z 函数) 给定两个字符串 \(a,b\),要求出两个数组:\(b\) 的 \(z\) 函数数组 \(z\).\(b\) 与 \(a\) 的每一个后缀的 L ...
- 题解-洛谷P4229 某位歌姬的故事
题面 洛谷P4229 某位歌姬的故事 \(T\) 组测试数据.有 \(n\) 个音节,每个音节 \(h_i\in[1,A]\),还有 \(m\) 个限制 \((l_i,r_i,g_i)\) 表示 \( ...
- 题解-洛谷P4724 【模板】三维凸包
洛谷P4724 [模板]三维凸包 给出空间中 \(n\) 个点 \(p_i\),求凸包表面积. 数据范围:\(1\le n\le 2000\). 这篇题解因为是世界上最逊的人写的,所以也会有求凸包体积 ...
- 题解-洛谷P4859 已经没有什么好害怕的了
洛谷P4859 已经没有什么好害怕的了 给定 \(n\) 和 \(k\),\(n\) 个糖果能量 \(a_i\) 和 \(n\) 个药片能量 \(b_i\),每个 \(a_i\) 和 \(b_i\) ...
随机推荐
- SSL/TSL 原理( 握手原理和传输原理)
本文参考<计算机网络 自顶向下方法> 目录 背景 通信的4要素 SSL/TLS in Detail 通讯保证 The Handshake Protocol 1. Initial Clien ...
- 拿来即用:用C+JS结构来处理JSON数据
[面对的问题] 在物联网产品的开发过程中,对JSON格式的数据处理是一个强需求,例如亚马逊的 AWS IOT平台,设备与后台之间的通讯数据都是JSON格式,先瞄一眼大概的样子: 这是一个真实产品的通讯 ...
- 网易java高级开发课程 面对上亿数据量,网易用啥技术?
- ImageLoader在Listview中的使用
图片加载框架之ImageLoader 1_特点 1)多线程下载图片,图片可以来源于网络,文件系统,项目文件夹assets中以及drawable中等 2)支持随意的配置ImageLoader,例如线程池 ...
- android 中IntentService的使用场景
IntentService是继承并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统的Service一样,同时,当任务执行 ...
- Python3-算法-冒泡排序
冒泡排序 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来,走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成,这个算法的名字由来是因为越大的元素 ...
- mysql语句基本练习
select ename,job from emp where job in ('MANAGER','ANALYET','SALESMAN') 1.查询出工作岗位为MANAGER.ANALYST.SA ...
- Docker搭建Rancher平台
sudo docker run -d --restart=unless-stopped -p 8080:8080 rancher/server service docker resatrt启动失败 ...
- for循环里的break,continue和return有什么差别
break: 此语句导致程序终止包含它的循环,并进行程序的下一阶段(整个循环后面的语句),即,不是跳到下一个循环周期而是退出循环.如果break语句包含在嵌套循环里,它只跳出最里面的循环. 如下代码 ...
- .Net Core api 中获取应用程序物理路径wwwroot
如果要得到传统的ASP.Net应用程序中的相对路径或虚拟路径对应的服务器物理路径,只需要使用使用Server.MapPath()方法来取得Asp.Net根目录的物理路径,如下所示: // Classi ...