思考
记录一些日常思绪见闻,保持脑子清晰。。。
欢迎评论见解。。。
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\)
2021.12.24
大噶好啊,今天平安夜,提前祝大家圣诞节快乐。。。
所以我又趁着假期来更新解题报告了,这次是 NOIP 2021。
下次估计还能把 USACO 更了。
看了一下我是感觉难度比去年高了不少。
NOIP 2021
[NOIP2021] 报数
直接筛法就好。
遇到一个数,如果没有被筛过,则将其进行拆分判断是否数位上含有 \(7\),然后再将其倍数标记。
然后对于合法数字,我们将其记录在一个单独的数组中并记下其在这个数字中的序号。
这样输出时输出询问值在数组中的下一个元素即可。
虽然复杂度是 \(O(n\log n)\) 的,但是有极大优化空间且每次询问只需要 \(O(1)\)。可以通过本题。
[NOIP2021] 数列
看着有点像计数。
原来是计数 dp 啊,那没事了。
考场上遇见的话,先写个记忆化拿 50 分。
然后有记忆化自然可以考虑 dp 了。
我们为了满足 dp 的无后效性,我们可以考虑从低位往高位转换,因为低位的进位对高位有影响。
每次考虑将同一指数的所有数的贡献同时加入 \(S\)。
所以我们需要记录四种状态:
- 当前枚举到 \(2^i\) ;
- 序列中已经取 \(j\) 个数;
- \(k\) 个低位的 \(1\);
- \(l\) 个低位的 \(1\);
所以有转移方程:
预处理幂和组合数就可以通过了。
复杂度是 \(O(mn^4)\)。
应该是可以滚动数组的。。。
[NOIP2021] 方差
好题。
模拟退火可以拿很高的分数,考场上的话推荐一写。
这题要我们求
我们设 \(S=\sum_{i=1}^n a_i\)
不难发现一次操作的本质是交换了差分数组的相邻两项。
因为对于 \(i\) 两边做差分的结果从原来的 \(a_i-a_{i-1},a_{i+1}-a_i\) 变成了 \(a_{i+1}-a_i,a_i-a_{i-1}\)。
然后呢?
不会做了。。。
我们打开神 syksykCCC 的题解发现一个性质我们没有发现。
对于最优解的数列,新的差分序列必须是单谷序列。
感性理解一下,在单谷情况下,你仍然去交换差分数组的两个相邻元素 \(d_i,d_{i+1}\),这样函数的变化图象会产生波动,存在波动的情况下差异自然也就变大,因为在同一个区间内折线产生的差异贡献经过了多次,而方差的本质就是差异大小,所以方差会变大。
虽然很不严谨,但是有助于理解。
当然,还要注意的是本题给的序列的单调不递减的,在这样的操作下可以保证差分永远 \(\geq 0\)。
@MoYuFang 这篇题解有很详细的证明可以参考一下。
这样可以 dp 了。
我们考虑 \(f_{i,j}\) 表示考虑前 \(i\) 项,当前和为 \(j\),最小的平方和是多少。
我们排序差分数组,然后每次考虑对于每项直接移到左端或右端。
- \(d_i\) 放在右端,则当前位置的值为 \(s=\sum_{k=1}^i d_k\),有 \(f_{i,j}=f_{i-1,j-s}+s^2\);
- \(d_i\) 放在左边,这 \(i\) 个数都需要 \(+d_i\),所以总和 \(+i\times d_i\),平方和推一下式子发现变化为 \(2d_i\times j+i\times d_i^2\),于是有 \(f_{i,j}=f_{i-1,j-i\times d_i}+2d_i\times j+i\times d_i^2\)。
复杂度是 \(O(n^2a)\) 的,最后 \(n\) 比较大的点 \(a\) 比较小,考虑一下很多方差会为 \(0\),把 \(0\) 放在里面就好,这样就是 \(O(na^2)\) 的。
[NOIP2021] 棋局
2 道 dp 都是好题,而且码量清新。
然后眼睛一睁看到数据结构当场去世。
先暴力,bfs。
就随便讲几个思路吧。
棋子会将图分裂,如果直接添加棋子很难维护分裂过程,于是离线倒过来做删除棋子的操作,这样就成了维护连通块等一系列操作了。
一类边直接暴力查询。
二类边维护并查集并,不应和三类边有冲突。
三类边直接维护连通块,需要删点和合并操作,通过线段树合并+并查集实现。
口胡了一下感觉很有道理,不知道猴年马月可以补代码。。。