提高组杂题选做
P17636
套路化的将 \((a_i\oplus a_j)^2\) 拆开,那么我们只需要考虑某两位的贡献。枚举这两位后需要统计子树内的 \(d\) 邻域信息,这是经典问题,长剖优化即可,复杂度 \(O(n\log^2 V)\)。
P14311
注意到一个区间的最大值肯定要选,然后根据最大值位置 \(p\) 将问题砍成 \([l,p]\) 和 \([p,r]\) 两端,下面只考虑 \([l,p]\) 的部分。考虑两个位置 \(i<j\),如果 \(a_i>a_j\),可以发现的是 \(j\) 作为 \(x\) 一定是不优的,因此有结论:合法的能作为 \(x\) 的位置是 \([l,p]\) 的前缀最大值。
此时我们已经确定了 \(x,z\),考虑确定 \(y\)。考虑两个相邻的前缀最大值位置 \(i,j\),对于 \(x=i\) 来说,只有 \(y\in (i,j]\) 时才有可能更优。而如果 \(y=j\) 合法,那么比 \(i\) 靠前的所有前缀最大值都不需要考虑了,因为它们一定被 \((i,j,p)\) 偏序;否则我们找到 \((i,j)\) 区间内的最大值计算贡献即可。
考虑暴力跳前缀最大值的复杂度,注意到我们的条件是当 \(a_p-a_j\ge a_j-a_i\) 时就跳出,所以每次跳满足 \(a_p-a_j<a_j-a_i\),也就是 \(2(a_p-a_j)<a_p-a_i\),因此每跳一次 \(a_p-a_i\) 至少翻倍,最多跳 \(O(\log V)\) 次,复杂度 \(O(n\log n\log V)\)。
CF2252E
有经典等式 \(a+c=(a\oplus c)+2(a \and c)\),所以有 \(a + c = (a\oplus c)+2(a \and c) = 2b=2(a\oplus c)\),于是有 \(a\oplus c=2(a\and c)\),二进制下考虑就是 \(a_i \oplus c_i=a_{i-1}\and c_{i-1}\)。对这个条件做数位 dp,复杂度 \(O(T\log n)\)。
感觉直接对着题目条件做数位 dp 也行吧。
CF2081D
完全图上的最小生成树问题考虑 Boruvka 和 Kruskal。这个题 Boruvka 也能做但是比较拉,考虑 Kruskal。Kruskal 的关键在于去掉无用边,我们考虑一个点 \(x\),枚举所有区间 \([kx,(k+1)x)\),考虑区间中的两个数 \(y,z\),如果我们连 \((x,z)\) 是不如连 \((x,y),(y,z)\) 的。因此对于所有区间我们只需要保留最小的点,总共只有 \(O(n\log n)\) 条边,复杂度 \(O(n\log^2 n)\),如果用线性排序方法可以做到单老哥。
CF2057E2
首先二分将第 \(k\) 大限制转化掉,相当于在 \(0,1\) 图上要求 \(s\to t\) 最短路 \(\le k\)。暴力做的话肯定不行,因为这是一个全源最短路问题。特殊的点在于我们的图只有 \(0,1\),而 \(0\) 边连接的联通块可以视作一个点。在我们二分的值变化的过程中只会发生 \(1\to 0\),相当于每次加入一条 \(0\) 边,维护联通块。那么很显然的是这个过程只会发生 \(O(n)\) 次,也就是说我们更新最短路的时刻只有 \(O(n)\) 个,而更改边权后重构全源最短路是 \(O(n^2)\) 的,因此我们就得到了 \(O(n^3)\) 的做法。
CF2141H
注意到如果直接满足要求输出 0 0,否则最大值一定是 \(n-1\)。
操作的本质是新加一个点,连边是原先两点的交。正难则反,在补图上考虑问题,就是两点的并,最后要求存在一个联通块是单点。注意到将一个补图联通块变成单点需要 \(siz-1\) 次,因此求出最小的补图联通块即可。求补图联通块是一个经典问题,复杂度 \(O((n+m)\log n)\)。
CF2253F
太牛。分析得到只有形如 \((a,2a,3a,4a)\) 的四元组能取到最大值,并且对于 \(n\ge 4\) 都一定有这样的四元组,因此我们的条件就是选出尽可能多的数,使得不存在 \((a,2a,3a,4a)\) 即可。
这个问题是一个上古的经典问题,先枚举一个基数 \(k\) 满足 \(2\nmid k,3\nmid k\),然后构造表格 \(A\) 满足 \(A_{i,j}=k\times 2^i\times 3^j\),条件等价于不能同时选 \((i,j),(i+1,j),(i+2,j),(i,j+1)\)。由于格子的长宽均不超过 \(\log V\),所以可以直接用轮廓线 dp 求解。
P8978
先二分转化为 \(-1,1\) 序列,然后考虑 dp。一个区间能被推平的条件是 \(s_r-s_{l-1}\ge 1\),我们考虑被操作区间的性质,简单推导后可以得出:所有被操作区间两两包含。
然后我们可以得到一个 dp:设 \(f_{l,r}\) 表示操作完 \([l,r]\) 的最少次数,转移枚举下一个区间 \([a,b]\subseteq [l,r]\) 即可,复杂度 \(O(n^4\log n)\),太拉了。注意到另一个性质:操作次数不超过 \(O(\log n)\),因此我们考虑值域定义域互换,设 \(f_{i,l}\) 表示最大的 \(r\) 满足 \(i\) 次操作内可以清空 \([l,r]\)。
令 \(val_{i,l}\) 表示删空 \([l,f_{i,l}]\) 的贡献,也就是 \(f_{i,l}-l+1-s_{f_{i,l}}+s_{l-1}\),那么转移的时候枚举 \(l'\ge l\),那么 \(f_{i,l}\) 就是找到下标最大的前缀和至少为 \(s_{l-1}+1-val_{i-1,l'}\) 的下标,预处理后单次转移复杂度 \(O(n^2)\),总复杂度 \(O(n^2\log^2 n)\)。扫描线后可以优化到 \(O(n\log^3 n)\),不过常数很大难以通过。
想要优化一定需要进一步挖掘单调性。首先被包含的区间一定没有用,因此我们可以认为左右端点均单调。进一步的,如果 \(l<l'\) 且 \(val_{i,l}>val_{i,l'}\),那么 \(l'\) 也没有用了。所以此时我们剩下的区间满足左右端点递增的同时 \(val\) 递增。令 \(g(i)\) 表示下标最大的前缀和至少为 \(i\) 的下标,那么我们就是找到满足 \(g(s_{l-1}+1-val_{i-1,l})\ge f_{i-1,l}\) 的最大的 \(g\)。
从后往前看当前剩下的区间,显然有 \(-val_{i-1,l}+1\) 递增。由于 \(g\) 也有单调性,所以如果可以保证 \(s_{l-1}\) 单增,那么扫描线的过程中不等式左半部分会一直变小,也就是不合法的不会再变得合法;同时还可以保证剩余的区间的 \(g\) 值也单调不增,于是我们就可以用单调队列来维护 \(g\)。现在只需要考虑如何让 \(s_{l-1}\) 单增,注意到如果 \(i<j\) 且 \(s_{i-1}<s_{j-1}\),让 \(j\) 作为左端点不如直接延伸到 \(i\),区间总和一定不会变小。然后就做完了,复杂度 \(O(n\log^2 n)\)。
这个题后半部分的运用了三次单调性分析才得出了一个单次 \(O(n)\) 的转移,非常精妙。
CF2261G
先考虑怎么求 \(f(a)\),令 \(A,B\) 为 \(a\) 的异或和 \(a\) 的与,那么分析可知,我们可以找到最高的满足 \(A_i=1,B_i=0\) 的二进制位 \(i\),那么 \(A_{\le i}\) 可以直接被清空,我们只需要对 \(>i\) 的位计数即可。
位运算操作不好直接算总和,我们肯定考虑拆位变成加减法。仔细分析一下,我们实际上是找到最高的 \((1,0)\),并计算它上面 \((1,1)\) 的数量计入答案。注意到如果存在 \((1,1)\) 那么不可能存在 \((0,1)\),也就是出现 \((0,1)\) 的区间是不可能有贡献的,所以最高的 \((1,0)\) 上面只有 \((1,1)\) 和 \((0,0)\) 两种情况,也就是说有贡献的区间的上面部分完全相同。
那么有了这个性质求解就简单了,求区间的与可以用经典技巧拆成 \(O(n\log V)\) 个区间,异或和可以直接差分后转化为求一个区间内等于某个数的数的数量,用一个桶维护即可,由于我们要拆位所以总复杂度 \(O(n\log^2 V)\)。
CF2055E
考虑如果已知一个清空的顺序怎么做,每一次清空的时候需要尽可能往前面已经清空过的位置放,因为如果往后放它一定会被再操作一次,这样会增加贡献。而基础的贡献就是 \(\sum a_i\)。
那么具体的过程就是有两个序列 \(a_i,b_i\),初始有两个变量 \(s,ans\)。每一轮执行 \(ans \leftarrow ans + \max(0, a_i-s)\) 以及 \(s=\max(0,s-a_i)+b_i\)。这个过程可以看作一个长为 \(2n\) 的序列 \(-a_1, b_1, -a_2, b_2,\cdots\),然后维护一个前缀和,每次前缀和 \(< 0\) 时加上它的绝对值然后将它变成 \(0\),求贡献总和。这是一个非常经典的结论,答案是这个序列的前缀和最小值的相反数。
换句话说,假设固定了清空顺序,设 \(c_i=\sum_{j=1}^i a_j - \sum_{j=1}^{i-1}b_j\),则多出来的贡献是 \(\max c_i\)。然后考虑让 \(\max c_i\) 尽可能小,考虑邻项交换法贪心,那么排序条件应该是 \(\max(a_x,a_x-b_x+a_y)<\max(a_y,a_y-b_y+a_x)\),但这个条件实际上还不能做邻项交换法。不过注意到我们可以分 \(a_i-b_i\) 的正负性讨论一下,负的放前面一定更优,因为它们对后面的贡献为负。然后此时再去考虑正负各自的排序条件即可。
CF2077D
先考虑枚举最大值后怎么做,\(O(n\log n)\) 的贪心二分是显然的,不过我们有 \(O(n)\) 做法。考虑从前往后构造,假设当前已经构造好了 \(a_1\sim a_{i-1}\) 的最优子序列 \(p_1\sim p_k\),我们现在考虑加入 \(a_i\)。如果 \(a_i\) 可以顶替前面的某个 \(p\),我们就找到最靠前的能被顶替的 \(p\),需要满足:
- \(a_i>p_j\)。
- 总和减去 \(p_j\sim p_k\) 后加上 \(a_i\sim a_n\) 可以满足条件。
注意到如果存在 \(p_j<p_k\) 说明 \(p_k\) 不满足第二个条件,随着 \(i\) 的增加条件只会越来越严,所以 \(p_j\) 不可能再被顶替了,于是我们只需要维护末尾的 \(p\) 递减段,每次拿 \(a_i\) 暴力弹栈即可,复杂度 \(O(n)\)。
但是现在我们不能枚举所有最大值,不过我们知道多边形相关的题目大概率要用到 \(O(\log V)\) 次的分析结论,对本题也是一样的。注意到如果我们求解了最大值 \(=x\) 的答案,那么我们不必关心最大值 \(\in (\frac{x}{2},x]\) 的答案,因为如果有合法方案的话加入 \(x\) 依然满足条件,并且字典序更大。所以我们只需要枚举 \(O(\log V)\) 个最大值,复杂度 \(O(n\log V)\)。
ARC232B
根据经典套路我们应该把 \(A_i\) 和 \(B_i\) 连边,但是连边后发现直接做会比较困难,原因在于题目中的限制太强了,我们只有在两个 \(A_i\) 相等的情况下才能操作。考虑弱化一下,我们声称如果两张牌可以各选出一面使得数字相同,就可以将两张牌翻转。这个问题显然是一个简单题,在连完边后跑出一条最短路,这样只有开头结尾的两张牌会被翻转奇数次,满足了题目要求。
然后我们声称这和原问题是等价的。感性理解一下大概是,我们的路径上有 \(n\) 条边,把每张牌放到 \(A_i\) 上,由于初始时 \(B_1,B_2\) 上不会有牌,所以实际上是把 \(n\) 张牌放到了 \(n-1\) 个点上,根据抽屉原理显然会有两张牌初始放在同一个点上,那么这两张牌就可以按照原问题的限制进行操作,这样的话后面的过程继续进行下去就是原问题的一个解。
CF2208E
开局先做两个观察,第一个是我们的序列 \(b_i\) 的合法条件,根据经典结论条件等价于所有 \((b_i,i)\) 区间不交或包含。第二个是注意到 \(b_i\) 和 \(a_i\) 的笛卡尔树形成双射,因此我们可以做一个区间 dp。
设 \(f_{l,r}\) 表示当前笛卡尔树区间为 \([l,r]\),根链上第一个向左走的点是 \(l-1\),那么这个区间内的最小值的 \(b_i\) 就是 \(l-1\)。枚举这个最小值所在位置,有转移方程 \(f_{l,r}=\sum f_{l,i-1}f_{i+1,r}\),复杂度 \(O(n^3)\)。
上面这个做法显然没有什么优化前途,但是我们可以从这里入手讨论。假设我们当前在处理 \([l,r]\),先将这个区间内部所有已知区间递归下去求解方案数,然后考虑剩下的没有被覆盖的 \(-1\)。这个时候 dp 就非常简单了,因为我们相当于只有 \(b_i=-1\) 和 \(b_i=i-1\) 两种情况,使用前缀和优化可以做到单次 \(O(n^2)\),而我们每个区间要 dp 的 \(i\) 的个数总和是 \(O(n)\) 级别的,所以总复杂度还是 \(O(n^2)\)。
QOJ20740
神了。感受一下,因为我们不会,所以我们假定每个点的决策是走到目标叶子节点后开始绕圈。先把目标叶子节点当做根方便讨论,然后可以感受到以哪个叶子当根是不影响的,因为显然可以相互转化。
那么此时我们相当于有若干个 \(dep_i\),要求每个点绕圈后可以达到同一时间。假设每个点绕圈长度为 \(len_i\),那么要求存在 \(k_i\) 使得 \(dep_i+k_i\cdot len_i\) 全部相同。我们的合法条件就是 \(\gcd(len_i)\mid \gcd(dep_i)\)。
现在只需要让 \(\gcd(len_i)\) 尽可能小,很明显的是我们可以通过走到某个叶子节点再走回来构造出 \(len_i=2dep_i\)。接下来考虑有没有别的构造,注意到如果走 \(rt\to a\to b\to rt\) 还可以构造出 \(len_i=2dep_a+2dep_b-2dep_{\text{lca}(a,b)}\)。综合上述情况,我们建出所有叶子构成的虚树,那么实际上最小的 \(\gcd(len_i)\) 就是虚树上所有点的 \(dep\) 的 \(\gcd\) 的二倍。
根据这个直接判定可以做到 \(O(n\log n)\),瓶颈来自求 \(\gcd\)。但是根据上面的分析我们知道 \(\gcd(len_i)\mid 2\gcd(dep_i)\),所以最后我们只需要考虑 \(\gcd\) 中 \(2\) 的因子个数即可,复杂度 \(O(n)\)。
P14364
停止使用延迟钦定,使用容斥技巧。考虑直接钦定哪些人最后被录取,那么这一定是 \(s\) 的一个子集。设 \(x_i\) 表示 \(1\sim i-1\) 中没有被录取的人数,那么分类讨论第 \(i\) 位上的值 \(c\):
- 如果不被录取,则要求 \(c\le x_i\);
- 如果被录取,要求 \(c> x_i\)。
看到这样两个限制应该条件反射进行容斥,将 \(c>x_i\) 容斥为任意减去 \(c\le x_i\),同方向的限制只需要保证 \(x_i\) 递增就可以直接做了。dp 状态就是 \(f_{i,j,k}\) 表示 \(1\sim i\) 中有 \(j\) 个没有被录取,已经填了 \(k\) 个位置上的值。转移是 \(O(1)\) 的,总复杂度 \(O(n^3)\),代码量和细节比延迟钦定少一万倍,跑的比延迟钦定快一万倍。

浙公网安备 33010602011771号