一句话题解(2020.4.10 ~ ????.??.??)
日常偷懒。
有些题因为实在太懒了,所以没写,如果在口胡还望各路大佬能指正。
UOJ
- 386,考虑按大小排序,然后枚举最大的大小,考虑从大到小枚举较小值,显然你会贪心地选其中牢固程度最大的 $m$ 个。然后考虑用链表维护能够加入后缀 $m$ 大的所有数,显然除了最初的 $m$ 个一定是单调递增的。每次暴力从后往前遍历链表,将里面的数加入某个数据结构,如果不能加入就把这个数从链表上删除,如果这个数以及比新加入的大,那么就停止遍历。每次只用枚举到的地方更新答案。对于不在最初 $m$ 个数最多被遍历 $m$ 次,通过一些简单的 trick 可以做到 $O(nm)$。
- 61,对于每条链,预处理若干个连通块,然后每个连通块链上相邻的点连边。处理这个可以用链表 + bfs。然后边可以分为连续的链和独立的边,对前者求 MST 得到 $n - 1$ 条边,后者只有 $O(p)$ 条边,然后跑一边 Kruskal 就行了。
Codeforces
- 1076G,不难把问题转化成有向图博弈。大概每个 $b_i$ 变成一个长为 $b_i$ 的链,显然这个只和奇偶性相关,所以可以让 $b_i \leqslant 2$。注意到边上 $m$ 个至多有一个必败的局面,维护一下必败的局面距离边界的距离就可以了。
- 1342F,先把问题转换成划分成尽量多的集合,并且每个集合中选一个代表元素,按代表元素下标对集合排序,排序后的每个集合的和单调递增。考虑朴素做法是 $f_{i, Su, sum}$ 表示上一个选择的集合的代表元素的位置为 $i$,使用过的元素 $S$,上一个集合的和为 $sum$ 的时候最多能划分为多少个集合,转移枚举下一个集合,但是注意到处理判断 sum 递增的时候,并不关心前一个集合具体选择的是什么,因此调换一下 集合的和 和 最多能划分为多少个集合的位置 的位置就行了。另外代表元素的位置显然是选择 $i$ 之后第一次出现在新集合中的位置,因此总复杂度为 $O(n^23^n)$。
luogu
- P5655,注意到算一堆数的 lcm 可以每次加入一个,然后计算它和前面的 gcd。考虑分治,处理跨过中点的询问,预处理前缀和后缀的 lcm,然后合并的问题是给定两组数求出它们乘积的 gcd,暴力做法是枚举任意两个数,如果它们 gcd 大于 1 就把它除掉然后算进答案。不难发现枚举 $l$ 可以维护出所有 $r$ 的答案,使用一些精妙的实现可以做到 $O(Tn^2)$。
loj
- loj 6696,$d = 4$ 的情况,某个四次单位根能用 $1, \omega_4$ 线性表示,而 $d = 6$ 的时候,某个六次单位根能用 $1, \omega_6$ 线性表示,因为 $\omega_6^0 + \omega_6^{3} = 0, \omega_6^0 + \omega_6^2 + \omega_6^4 = \omega_6^0 + \omega_6^2 - \omega_6^1 = 0$,然后求 $K$ 次幂可以求偏导然后对比系数。
- loj 3189,考虑一个 $x$ 能够覆盖一段区间的询问,考虑只维护这一些区间的并集,显然对于加 $t$ 也是能转移。不难证明状态数为 $O(n\log_{\frac{p}{p-1} r})$。