2022杭电多校部分好题题解(简要口糊)
作者:互联网
Day 1
-
枚举两个点,计算剩下一个点的选取方法:
- 题解做法:从小到大加入边,相当于要求与其中一个点右边而与另一个没有,直接 \(bitset\) 维护,\(\mathcal O(\frac{Tn^3}{\omega})\) 即可通过。
- 考场做法:注意到与一个点曼哈顿距离 \(\le d\) 的点形成一个正方形。两个正方形的是矩形,于是就变成一个二维偏序,复杂度 \(\mathcal O(Tn^2)\)。
-
题目中的条件意味着不会存在一条边被两个环经过,因此原图是仙人掌。然后直接莫比乌斯反演变为求 \(gcd\) 为 \(x\) 的倍数的路径数,将边权为 \(x\) 的倍数的边建出来 \(dp\) 即可。
-
枚举某一个点是通过哪种方式被覆盖的,再加入任意一个无法通过这种方式被一起覆盖的其他点,即可确定仅有的三个可能的位置,直接判断即可。
-
将每个值为 \(i\) 的数字视为 \(2^{n-i}\),则只要出现 \(2^n\) \(Alice\) 赢,每一步 \(Bob\) 是选一个集合乘 \(2\)。于是每一步总和都不可能增加,初始总和必须要 \(\ge 2^n\),同时如果总和 \(\ge 2^n\) 则 \(Alice\) 每一步一定有方法分为两个总和 \(\ge 2^{n-1}\) 的集合,可以继续递归下去分。因此总和 \(\ge 2^n\) 则 Alice 获胜,否则 Bob 获胜。
Day 2
-
离线询问,倒着扫一遍所有修改,每一个修改 \([l,r]\) 相当于将 \(x>r\) 的询问的 \(x-=r-l+1\)。注意到只需要求所有询问的答案异或和,因此同一位置的相同查询可以地抵消,只需用 \(bitset\) 维护当前哪些地方有询问,再倒着扫一遍所有修改即可做到 \(\mathcal O(\frac{n^2}{\omega})\)。赛时暴力艹过去了。
-
记 \(dp_i\) 表示从 \(0\) 级升级到 \(i\) 级的期望次数。设当前买了一本书 \((a,b)\),记 \(x=\frac{a}{A},y=\frac{b}{B}\)。
有 \(dp_{i+1}=\min(dp_{i+1},dp_i+(1-x)(1-y)(dp_{i+1}-dp_i)+(1-x)ydp_{i+1})+1\)。
可以发现选择买这本书当且仅当 \(dp_i+(1-x)(1-y)(dp_{i+1}-dp_i)+(1-x)ydp_{i+1}\le dp_{i+1}\)。
展开式子得到 \(dp_{i+1}\ge dp_i\frac{x+y-xy}{x}\)。
虽然不知道 \(dp_{i+1}\) 的具体值。但将所有可能的书按照 \(\frac{x+y-xy}{x}\) 排序,我们一定会选择一个前缀,枚举前缀的长度计算贡献,取最优解即可得到 \(dp_{i+1}\)。复杂度 \(\mathcal O(kAB)\)。
-
将相邻的相同字符合并到一起,使用栈维护当前的字符串。若在加入 \(k\) 个 \(c\) 后目标串第一次作为当前串的子串出现,则一定满足目标串的最后一段相同字母为 \(len\) 个 \(c\),并且去掉最后 \(\max(len,k)\) 个字符后的部分是加入前串的后缀,使用哈希判断即可。这里的哈希可以将连续相同字母压缩到一起,即可快速判断。
-
题意即为选择最小的边集使得,每个最大权值生成树前经过至少一个被选择的边。
如果从图中删去某条边会导致最大生成树权值增加,那么选择这条边就行了。
否则,最终被选择的一定是一些权值相同的边,枚举权值 \(w\),用 \(kruskal\) 将 \(\ge w\) 的边全部加入,此时每个连通块内权值 \(=w\) 的边构成相互竞争关系,相当于要选择它们中最少的边使得图不连通,跑无向图最小割即可。由于每一组的边数不超过 \(100\),所以可以通过。
Day 3
-
记 \(sum_s\) 为点集 \(s\) 的糖果数之和,一个朴素的做法是记 \(f_{i,S}\) 表示将 \(S\) 集合的箱子分给 \(i\) 个孩子的最小代价。则有转移:
\[f_{i,S}=\min_{T\subset S}\{f_{i-1,T}+(sum_S-sum_T)^2\}=\min_{T\subset S}\{f_{i-1,T}+sum_T^2-2sum_Ssum_T\}+sum_S^2 \]直接转移是 \(\mathcal O(3^nm)\) 的,考虑优化。
这是一个经典的斜率优化的形式,将每个 \(T\) 看作直线 \(-2sum_Tx+sum_T^2\),如果能求出 \(S\) 子集对应的凸壳,就可以快速求解 \(f_{i,S}\)。求凸壳可以类似于高维前缀和:初始对每个状态 \(S\) ,凸壳中只包含 \(T=S\),然后从小到大遍历每一位,遍历到第 \(x\) 位时取出所有第 \(x\) 位为 \(1\) 的 \(S\),将 \(S\) 与 \(S \oplus (1<<x)\) 的凸壳归并起来即可,归并的复杂度为二者凸壳大小之和。因此总代价不超过每个最终凸壳大小的两倍,也就是 \(\mathcal O(3^n)\)。
这个复杂度依然无法接受,考虑折半优化,枚举 \(A\) 作为 \(T\) 的前半部分,以及 \(A\) 的超集 \(A'\) 作为 \(S\) 的前半部分,再枚举 \(S\) 的后半部分 \(B'\),寻找找一个 \(B'\) 的子集 \(B\) 作为 \(T\) 的后半部分,这里再使用之前的方法。对每个 \(A\) 花费 $\mathcal O(3^{\frac{n}{2}}) $ 的代价预处理所有 \(B'\) 子集的凸壳,再按照 \(sum_{A'}\) 递增的顺序枚举 \(A'\) 与 \(B'\),即可保证对于同一个 \(B’\), \(sum_S\) 递增,在凸壳上询问 \(x=sum_S\) 的点的纵坐标即可做到均摊 \(\mathcal O(1)\)。
于是总复杂度为 \(\mathcal O(2^{\frac{n}{2}}3^{\frac{n}{2}})=\mathcal O(6^{\frac n2})\)。
-
核心性质:对于一个点集,仅保留其凸包上的点,最小圆覆盖不会改变。
由于数据随机,一个点集的凸包上点数期望时 \(\mathcal O(\log n)\) 的,于是使用线段树维护区间凸包,最后对 \(\mathcal O(\log n)\) 个顶点运行最小圆覆盖算法即可。
-
核心性质:每个障碍的行数均为 \(w\),列数均为 \(h\)。
按 \(w\) 行一块,将矩阵分成 \(\lceil\frac{m}{w}\rceil\) 块,那么每个障碍要么完全属于某一块,要么经过相邻两块。于是每个矩形障碍对某个块的影响只能是:块的第 \(x\sim x+h-1\) 列的前若干行/后若干块是障碍。
对每一块找出经过这一块的矩形障碍,假设共有 \(k\) 个。以障碍的左右边界为分界点将这个块分为 \(\mathcal O(k)\) 个区域,每个区域内只有一个连续的行区间可以行走,由于每个障碍的宽度是相同的,可以使用单调队列 \(\mathcal O(k)\) 求出每个区域的可走矩形范围,就将这个块划分为了 \(\mathcal O(k)\) 个矩形。
如果相邻两个块都没有障碍,可以把它们直接合并起来,这样就将整张图划分为了 \(\mathcal O(n)\) 个矩形区域,在相连个矩形区域连边,在形成的图上求解即可:同一块内相邻的区域连边,相邻块之间相邻的区域需要连边,这可以通过双指针来找出上块的每个区域相邻的下块区域,总边数依然是 \(\mathcal O(n)\) 的。
由于需要排序,因此总复杂度是 \(\mathcal O(n\log n)\) 的。
-
记 \(f_{i,j}\) 表示从 \(i\) 出发能否只经过第 \(j\) 个询问中保留的边走到 \(v_j\)。离线询问,使用 \(bitset\) 存储,对每条边 \((u,v)\) 有转移 \(f_u|=f_v\&S\),其中 \(S\) 是保留了边 \((u,v)\) 的询问集合。
考虑如何求出所有的 \(S\)。将每个询问拆成两个事件:在 \(l\) 处加入,在 \(r+1\) 处删除,然后按时间顺序扫一遍所有事件,维护当前的 \(bitset\),即可求出所有的 \(S\)。
但这样一共需要 \(m+n\) 个 \(bitset\) 空间开不下。考虑每次处理 \(B\) 个事件,每次扫一遍这 \(B\) 个事件,求出每条边关于这 \(B\) 个事件的 \(bitset\) \(S\),再进行一次转移即可。最终复杂度 \(\mathcal O(\frac{nq}{\omega})+\mathcal O(m\frac{q}{B})\)。因此只要空间开得下,\(B\) 尽量开大即可。
标签:口糊,frac,每个,杭电多校,题解,sum,即可,mathcal,dp 来源: https://www.cnblogs.com/tqxboomzero/p/16495940.html