[HAOI2018]苹果树
嘟嘟嘟
这种计数大题就留给南方的计数神仙们做吧……
刚开始我一直想枚举点,考虑新加一个点在根节点的左右子树,以及左右子树大小怎么分配,但是这样太难计算新的点带来的贡献了。
后来lba又提示我枚举边,考虑每一条边的贡献。
这确实是一个好主意,枚举边的同时考虑边两侧的点数,但可怕的是我一直把他当成无根树来做,也就是忽略了树上打父子关系,导致少算了好多形态。
于是题解吵朝我挥了挥手。
既然是有根树,那么我们枚举每一个点,然后枚举的是这个点和他父亲的连边,这样就能不重不漏并且有顺序的枚举所有边了。
考虑点\(i\)这条边的贡献,就是\(size _ i * (n - size_i)\)。
\(size_i\)不确定,但根据题意是可以\(O(n)\)枚举的。
我们枚举\(size_i\),算出当\(size_i\)一定时,这个子树以及子树外有多少种形态。
先考虑子树内:不算标号有\(size_i !\)种形态,因为第一个点只有一种连接方法,第二个点有两种,第三个点有三种……所以\(size_i\)个点就\(size_i !\)种。当形态固定时,考虑标号:因为在\(i\)子树内只可能是标号比\(i\)大的点,所以有\(C_{n - i} ^ {size_i - 1}\)种。那么子树内的所有形态就是\(size_i ! * C_{n - i} ^ {size_i - 1}\)。
接下来我们考虑子树外:在生成点\(i\)的子树之前有\(i!\)种方式,然后我们考虑剩下的\(n - i - size_i\)个点的生成方式,为:\((i - 1) * i * (i + 1) * \ldots * (n - i - size_i - 1)\)。
所以子树外的点的生成方式就是\(i! *(i - 1) * i * (i + 1) * \ldots * (n - i - size_i - 1) = (i - 1) * i * (n - size_i - 1)!\)。
那么答案就出来啦:
\]
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 2e3 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
int n, mod;
In ll inc(ll a, ll b) {return a + b >= mod ? a + b - mod : a + b;}
ll fac[maxn], C[maxn][maxn];
In void init()
{
fac[0] = 1;
for(int i = 1; i <= n; ++i) fac[i] = fac[i - 1] * i % mod;
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] = inc(C[i - 1][j - 1], C[i - 1][j]);
}
int main()
{
n = read(), mod = read();
init();
ll ans = 0;
for(int i = 2; i <= n; ++i)
for(int j = 1; j <= n - i + 1; ++j)
ans = inc(ans, fac[j] * C[n - i][j - 1] % mod * j % mod * (n - j) % mod * fac[n - j - 1] % mod * i % mod * (i - 1) % mod);
write(ans), enter;
return 0;
}
[HAOI2018]苹果树的更多相关文章
- 【BZOJ5305】[HAOI2018]苹果树(组合计数)
[BZOJ5305][HAOI2018]苹果树(组合计数) 题面 BZOJ 洛谷 题解 考虑对于每条边计算贡献.每条边的贡献是\(size*(n-size)\). 对于某个点\(u\),如果它有一棵大 ...
- [洛谷P4492] [HAOI2018]苹果树
洛谷题目链接:[HAOI2018]苹果树 题目背景 HAOI2018 Round2 第一题 题目描述 小 C 在自己家的花园里种了一棵苹果树, 树上每个结点都有恰好两个分支. 经过细心的观察, 小 C ...
- [HAOI2018]苹果树(组合数学,计数)
[HAOI2018]苹果树 cx巨巨给我的大火题. 感觉这题和上次考试gcz讲的那道有标号树的形态(不记顺序)计数问题很类似. 考虑如果对每个点对它算有贡献的其他点很麻烦,不知怎么下手.这个时候就想到 ...
- [BZOJ5305][Haoi2018]苹果树 组合数
题目描述 小 C 在自己家的花园里种了一棵苹果树, 树上每个结点都有恰好两个分支. 经过细心的观察, 小 C 发现每一天这棵树都会生长出一个新的结点. 第一天的时候, 果树会长出一个根结点, 以后每一 ...
- [BZOJ5305][HAOI2018]苹果树 组合数学
链接 小 C 在自己家的花园里种了一棵苹果树, 树上每个结点都有恰好两个分支. 经过细心的观察, 小 C 发现每一天这棵树都会生长出一个新的结点. 第一天的时候, 果树会长出一个根结点, 以后每一天, ...
- [BZOJ5305] [HAOI2018] 苹果树 数学 组合计数
Summary 题意很清楚: 小 \(C\) 在自己家的花园里种了一棵苹果树, 树上每个结点都有恰好两个分支. 经过细心的观察, 小 \(C\) 发现每一天这棵树都会生长出一个新的结点. 第一天的时候 ...
- Luogu4492 [HAOI2018]苹果树 【动态规划】
题目分析: 思路不难想,考虑三个dp状态$f,g,d$. $g[i]$表示有$i$个点的堆的数量 $d[i]$表示有$i$个点的情况下所有的方案数中点到根的距离和 $f[i]$表示要求的答案. 不难发 ...
- HAOI2018苹果树
题解 首先所有生成树的情况树是\(n!\)的,因为第一次有1中方法,第二次有两种放法,以此类推... 然后我们发现距离这种东西可以直接枚举每条边算贡献. 于是我们枚举了一个点\(i\),又枚举了这个点 ...
- BZOJ.5305.[HAOI2018]苹果树(组合 计数)
LOJ BZOJ 洛谷 BZOJ上除了0ms的Rank1啦.明明这题常数很好优化的. 首先,\(n=1\)时有\(2\)个位置放叶子,\(n=2\)时有\(3\)个... 可知\(n\)个点的有标号二 ...
- 洛谷P4492 [HAOI2018]苹果树(组合数)
题意 题目链接 Sol 有点自闭,.我好像对组合数一窍不通(~~~~) Orz shadowice // luogu-judger-enable-o2 #include<bits/stdc++. ...
随机推荐
- virtualbox中 Ubuntu安装增强功能
1. 执行,等待,当提示按 Enter 时按下 2. 在文件管理中找到挂载的文件,切换到该目录,执行命令 sudo ./VBoxLinuxAdditions.run 3. 重启
- js 简单日历
源地址:https://jingyan.baidu.com/article/546ae185fa4f721149f28cbf.htm 文件:index.htm <!DOCTYPE html> ...
- angular 分页插件的使用
html: <pagination total-items="totalItems" ng-model="currentPage" items-per-p ...
- vue从入门到进阶:自定义指令directive,插件的封装以及混合mixins(七)
一.自定义指令directive 除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令.注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件.然而,有的 ...
- 用webpack2.0构建vue2.0超详细精简版
初始化环境 npm init -y 初始化项目 安装各种依赖项 npm install --save vue 安装vue2.0 npm install --save-dev webpack@^2.1. ...
- 纯CSS+HTML实现checkbox的思路与实例
checkbox应该是一个比较常用的html功能了,不过浏览器自带的checkbox往往样式不怎么好看,而且不同浏览器效果也不一样.出于美化和统一视觉效果的需求,checkbox的自定义就被提出来了. ...
- GitHub for Windows离线安装包
国内安装github客户端,真的很痛!! 偶然找到了离线安装包,感谢作者的资源分享!!! 地址:http://download.csdn.net/download/lyg468088/8723039? ...
- 24.Odoo产品分析 (三) – 人力资源板块(5) – 出勤(1)
查看Odoo产品分析系列--目录 安装"出勤"模块,管理员工的上下班打卡. 1. 签到与退签 安装完模块后,点击"出勤"主菜单: 点击中间的签到按钮,实现签到 ...
- loadrunner 脚本优化-参数化之Parameter List参数取值
脚本优化-参数化之Parameter List参数取值 by:授客 QQ:1033553122 参数取值选项 Select next row Update value on 以上两个选项是改变参数化取 ...
- JavascriptDom编程艺术(笔记)
如果想快速学习dom的话,建议去菜鸟教程,比较浅显易懂,实战性较强.我是看纸质的书,主要是花钱,心疼,所以看完,容易记住. 1.重点: .变量 -.var修饰 -.赋值,用=号,例如ver age = ...