# C
# 题目大意
给定一个数列
求
# 数据范围
# 题解
考前缀和,求
1 | int n; |
# D
# 题目大意
给你一个 行 列的网格 ,其中 .
表示空白地面, #
表示墙, E
表示安全出口,你要把每个 .
变成 ^ v < >
的其中一个,要求每个 .
到 E
的路径都是最短的
# 数据范围
- 确保每个
.
一定能抵达E
# 题解
题目要求的是,对于每个 .
,其要变成 > < ^ V
,沿着路径能走到 E
,并且距离最短,显然用 ,一开始把所有 E
的坐标都 进队列,然后不断迭代
1 | int dx[] = {0, 0, 0, 1, -1, 1, 1, -1, -1}; // 行 |
# E
# 题目大意
你有 个苹果, 个橙子, 串香蕉, 串葡萄
求把他们从左往右排成一排的方案数,要求
- 所有的苹果都在所有的香蕉的左边
- 所有的苹果都在所有的葡萄的左边
- 所有的橙子都在所有的葡萄的左边
求一共有多少种排列方式,答案对 取模
# 数据范围
# 题解
显然,题目的排列应该是这样的
1 | |----苹果----| |
我们可以发现,香蕉在葡萄最左端分界线的左右两端的个数,会影响最终答案,不放假设左端有 个,则有
- 左侧是在 个苹果, 个香蕉之间,插入 个橙子
- 苹果必须在香蕉前面,所以
苹果 - 香蕉
,一共有 个,即 个有顺序的空,插 个无顺序的球 - 把 个无顺序的球分成 个部分,答案是 C_{B+A+x+1-1}^{A+x+1-1}=C_{B+A+x}^
- 苹果必须在香蕉前面,所以
- 右侧是在 个葡萄中,插入 个香蕉
- 为什么是 个葡萄?因为香蕉是以最左侧的第一个葡萄为分界的,所以右侧的左边第一个必须是葡萄
- 也就是,一共有 个有顺序的空,插入 个香蕉
- 把 个球,分为 个部分,答案是 C_{C-x+D-1}^
这种理解成放球问题会有点绕,不妨这样理解
最终目的是实现 个 物品和 个 物品混合放的最终方案数,那不就是, 个位置,任选 或 吗,也就是
对照到上面两侧
- 左侧是 和 的排列,也就是 C_{A+x+B}^
- 右侧是 和 的排列,也就是 C_{D-1+C-x}^
1 | vector<int> fac(N), inv(N); |