记录一些日常思绪见闻,保持脑子清晰。。。
欢迎评论见解。。。
2021.09.13
- U群看到的:有一个最密排堆积的球阵(每个球周围有12个球紧密结合的那种),球阵中有两种球,红色蓝色,全部随机分布,从球阵中挑选出颜色相同且至少能堆积为一个正四面体的子球阵。
直接暴力。将同规模的紧密结构进行暴力或随机重排。
或者直接取出同色球匹配子球阵。
不会写也不会分析,征求原题。。。
- 还是U群:估算一个区间内所有数字的最小质因数的和的复杂度
群友:
oeis A088821
a(n) ~ n^2/(2 log n)
2021.11.26
果真是非常颓废,好久没更新了。
昨天是感恩节,趁着假期更新一下,就暂时决定 vp 一下 csp 和 NOIp 吧。
CSP-S 2021
[CSP-S 2021] 廊桥分配
CSP 的 t1,一道性质良好的签到题。
首先该题不保证单峰,所以无需考虑三分等奇怪做法。
因为廊桥之间没有限制,所以每次到达一架飞机我们将其安排到编号最小的廊桥。
我们考虑对某个区域加入一个廊桥的影响和性质。
如果我们加入一个廊桥,必然有一架飞机会停在这个廊桥边。根据题目性质,这架飞机的停留区间必须是最靠近上一个已选区间的。
也就是该飞机的到达时间必须最靠近上一架停留飞机离开时的时间。
现在需要知道的是怎么实现安排廊桥的过程。
建立两个堆,一个放空闲廊桥称为 \(h_1\),一个放停在机场的飞机称为 \(h_2\)。
首先对两种航班按照起飞时间排序。
然后当一架飞机落地时,我们先将起飞时间小于当前降落飞机的飞机移出 \(h_2\),然后再把他们对应的廊桥放回 \(h_1\)。 然后我们分配一个编号最小的廊桥给当前降落飞机,移出 \(h_1\),再把飞机放入 \(h_2\),最后该廊桥的贡献 \(+1\)。
我们分别对国内航班和国际航班进行以上过程。复杂度是 $ \Theta (n\log n)$。因为廊桥和飞机只会进出堆一次。
我们发现我们记录下的是每一个廊桥的贡献,那我们该怎么求总贡献的最优解。
我们已知,如果一个廊桥不空闲且是当前区域编号最大的,那么之前必然没有空闲廊桥因为我们每次分配的是编号最小的。
那么对于每个区域,我们发现其前缀和,就是给其安排廊桥数量的贡献。
听起来很抽象,我们将其显式地表达出来。我们设 \(f(x)\) 为到第 \(x\) 个航桥加入国内区域的贡献,设第 \(i\) 个廊桥在国内区域的贡献是 \(s_i\) 那么其本质是 \(\displaystyle \sum_{i=0}^{x}s_i\)。而设 \(g(x)\) 为从第 \(x+1\) 个廊桥开始到最后一个廊桥加入国际区域的贡献。
那么最后我们只需要判断给两个区域分配多少廊桥达到最大值,则我们的答案是:
[CSP-S 2021] 括号序列
\(n\leq 500\),一眼区间 dp。
设 \(f_{i,j}\) 为将 \([i,j]\) 区间的问号填满后可能的序列方案数。
对于区间有多种情况:
-
()
-
(A)
-
(S)
-
(SA)
-
(AS)
-
AB
-
ASB
我们可以 \(O(n)\) 预处理 S
串方便 \(O(1)\) 判断某个区间是否为 S
串。
对于区间 \([i,j]\) 我们分类转移:
- \([i+1,j-1]\) 是裸的
S
串直接转移。 - \([i+1,j-1]\) 是否可以为
AS
或SA
串。 - \([i+1,j-1]\) 为
ASB
串
对于第三种情况较难处理。
我们可以枚举断点 \(l,r\) 那么转移是 \(f_{i,l}\times f_{r,j}\) 且 \(s_{l+1,r-1}\) 是 S
串。
但是我们发现有些情况下两个断点会被重复计算,所以我们只需要强制只在第一个断点计算。所以给状态加一维表示能否进行后一次转移,所以只需要保证 \(f_{i,l}\times f_{r,j}\) 的第三维 \([0/1]\) 不同即可。
由于第三种要枚举 \(2\) 个断点是 \(O(n^4)\) 的,于是我们进行前缀和或者后缀和优化即可 \(O(n^3)\)。
[CSP-S 2021] 回文
据说是签到题,不过我觉得前三题难度都差不多。
由于得到的是回文串,那么我们在 \(a\) 中取出一个字符时放到 \(b\) 的末尾时,另一个仍存在于 \(a\) 中的字符取出的时间和在 \(b\) 中的位置是确定的。
同样,我们不难发现对于回文 \(b\) 串,\(b_{[1,n]}\) 和 \(b_{[n+1,2n]}\) 一定都是一个 \(1\) ~ \(n\) 的排列。
我们假设第一个取出 \(a_1\)
现在我们找到一个 \(a_k,(k\in[2,2n])\) 且 \(a_k=a_1\)。
现在我们将 \(k\) 作为分割点,那么我们接下来必须要在 \(a_{[2,k-1]},a_{[k+1,2n]}\) 中取字符。
而且这两个序列我们分别只能从左或者右取字符。
于是我们可以将它们考虑成 2 个栈。
我们设这两个栈为 \(s_1,s_2\)。
L
表示从 \(s_1\) 弹出一个元素放入 \(b\) 尾,R
是从 \(s_2\) 中弹出。
现在要求一个字典序最小的操作序列使得 \(b\) 为回文串。
还是利用之前那个结论,我们发现弹出一个元素时另一个存在于栈内的同元素应该在另一个对称的时间点也被弹出。所以此时另一个元素应该位于该栈栈底或另一边的栈底。因为保证弹出后另一边栈或当前栈的栈底相同的那个元素在对应位置弹出之前可以弹出其他的所有元素并保证数量对称。
所以很简单了,我们只需要每次弹出同时存在于两个栈之一的栈顶,和两个栈之一的栈底的元素,并同时删除这两个位置。如果存在 2 个这样的字符,优先选择 \(s_1\) 内的,因为需要保证字典序最小。
如果没有这种情况,说明这个字符弹出后无论如何都没办法让另一个达到匹配的位置,则是无解。
[CSP-S 2021] 交通规划
暂时不会,有待研究。。。
subtasks:
\(k\leq 2\) 网络流染色。
小数据直接暴力。
这样你就得到了优秀的暴力分。
没有时间严格地 vp,得分大概是 \(100+40+48+40\)