Solution Set - 杂题题解(一)
开个新类型的写法,一篇文章就贴十个题。
「JOI 2013 Final」现代豪宅
对每一个点拆出两个点分别表示行的边和列的边,两个点之间连上一条边权为 \(1\) 的边表示摁住按钮的代价。
注意到按按钮的地方只会是换向的地方,只对这些地方建图即可,注意特殊处理起点和终点。时间复杂度线性对数。
「XXI Open Cup, GP of Korea」Query On A Tree 17
带权重心很不好求,但是深度最小会不会有什么用,一个很难的被察觉的事情就是,深度最小的带权重心 \(u\) 一定满足其子树和大于总和的一半。
直觉是需要使用重链剖分,下一个问题就是如何求出带权重心,我们可以先求出某一个在 \(u\) 子树的点,再用两只 \(\log\) 的代价倍增出带权重心。
接下来考虑如何求这个点,我们使用线段树二分,找出某一段大于一半的后缀即可。时间复杂度两只 \(\log\)。
「CEOI2012」工作规划
二分答案,然后按电脑一个一个的填上位置,没了,时间复杂度线性对数。
「LOJ6187」Odd
问题其实等价于,求出有多少个字段,满足其「异或和」等于「出现过的数的异或和」。
设区间为 \([l,r]\),异或的前缀和为 \(s\),则答案的要求其实是 \(s_r\oplus s_{l-1}=h_{l,r}\),也就是 \(s_r=s_{l-1}\oplus h_{l,r}\),考虑扫 \(r\) 来维护 \(h_{l,r}\oplus s_{l-1}\),对于一个位置 \(i\),考虑维护做如下事情:
-
为 \([las_{a_i}+1,i]\) 异或上 \(a_i\)。
-
查询出等于 \(s_r\) 的所有数。
使用分块来维护这个数列,散块是简单的暴力,整块修改打标记,整块查询使用哈希表即可。
但是这样做错误率很高,需要随机每个数的权值,这样可以做到更高的正确率,注意权值要在 ull 级别。时间复杂度单根号。
「UR #2」树上 GCD
首先先容斥成只用求倍数的形式,然后处理掉两点为父子关系的情况。
根号分治:
-
\(d\le \sqrt{n}\),记 \(f_{u,d}\) 为 \(u\) 子树内距 \(u\) 为 \(d\) 的倍数的点,瞎转移一下即可。
-
\(d>\sqrt{n}\),启发式合并,从底向上做,加上倍数,同样瞎搞搞就行。
「CF797F」Mice and Holes
按坐标排序之后从左向右考虑。
考虑 DP,设 \(f_{i,j}\) 表示前 \(i\) 个洞进前 \(j\) 个老鼠,那么枚举有 \(k\) 只老鼠进第 \(i\) 个洞,有 DP 式子:
其中 \(s_{i,j}\) 表示前 \(j\) 只老鼠进前 \(i\) 个洞的最小距离。
枚举 \(j-k\),独立 \(s_{i,j}\),问题变成 \(f_{i,j}=s_{i,j}+\min(f_{i-1,k}-s_{i,k})\),其中 \(k\) 有一定范围,使用单调队列优化即可。
时间复杂度 \(O(n^2)\)。
「POI2011」SEJ
设最小的非零密码是 \(x\),那么密码集合也就是 \({0,x,2x,\ldots}\),也就是说 \(x|n\)。
注意到 \(a_k\) 是一个合法密码,那么 \(x|\gcd(a_k,n)\),同时 \(x\nmid a_i\)。
对 \(\gcd(a_k,n)\) 分解质因数,暴力检验这些质因数没有前途,我们考虑根据前面的 \(a_i\) 来进行检验。
每一次我们枚举 \(a_i\) 与 \(\gcd(a_k,m)\) 的共同因子,递归到这些因子下面做,最后求出最小的合法因数,那这个值就是我们需要的 \(x\)。
最后,输出 \(\frac{n}{x}\) 即可。
「联合省选 2022」最大权独立集问题
妈的,好几把难,题解约等于转载。
黑色高级树形 DP,设 \(f_{u,v,q}\) 表示在 \(u\) 的子树里 \(v\) 换出来,换进来的值的贡献系数是 \(q\),即会被交换 \(q\) 次。
\(q\) 不会超过 \(u\) 另外一个子树的大小,故实际上本质不同的状态数是 \(O(n^2)\) 的,只需要使用 vector 存下每一个状态就可以满足空间限制。
对 \(u\) 的形态来分讨:
- 叶子,那么 \(f_{u,u,1}=a_u\)。
- 只有左儿子 \(v\),分两种情况讨论:
- 先换进来再换到子树去:\(f_{v,w,q-1}+a_u\to f_{u,u,q}\),换出去的是 \(u\),而换进来的贡献系数加 \(1\),可以直接枚举 \(v\) 的状态暴力转移。
- 先换到子树再换进来:\(f_{v,w,q}+qa_u+a_w\to f_{u,w,1}\),换出去 \(w\) 且上面换进来的一定是 \(u\),故增加 \(qa_u+a_w\),同样可以直接枚举 \(v\) 的状态暴力转移。
- 有两个儿子 \(y,z\),下面钦定 \(y\) 是左儿子,\(z\) 是右儿子,共三种顺序转移:
- 父边 - 左儿子边 - 右儿子边,这里表示的是操作边的顺序,\(f_{y,w,p-1}+f_{z,v,q}+a_u+a_wq\to f_{u,u,p}\),换出去 \(x\),左子树换进去某个值,换出 \(w\),\(w\) 再换进右子树,在这里统计答案。
运用参变分离的思想,记 \(f1_q=\min(f_{z,v,q})\),\(f2_w=\min(f1_q+a_wq)\)。这两个可以在 \(O(lsiz\times rsiz)\) 的时间内统一预处理出来,得到 \(f_{y,w,p-1}+f2_w+a_u\to f_{u,u,p}\),可以暴力转移。 - 左儿子边 - 父边 - 右儿子边:\(f_{y,w,p}+f_{z,v,q-1}+pa_u+a_w\to f_{u,w,q}\),\(w\) 连换两次直接换出去,而 \(u\) 去到左子树,外面来的点进入右子树,\(u\) 这个点被换出去。
同上,预处理 \(f3_w=\min(f_{y,w,p}+pa_u)\),则原式会变成 \(f3_w+f1_{q-1}+a_w\to f_{u,w,q}\),同样可以暴力转移。 - 左儿子边 - 右儿子边 - 父边:\(f_{y,w,p}+f_{z,v,q}+a_up+a_wq+a_v\to f_{x,v,1}\),模拟一下大概就能理解?
预处理 \(f4_q=\min(f3_w+a_wq)\),则转移可以写成 \(f4_q+f_{z,v,q}+a_v\to f_{x,v,1}\)。
- 父边 - 左儿子边 - 右儿子边,这里表示的是操作边的顺序,\(f_{y,w,p-1}+f_{z,v,q}+a_u+a_wq\to f_{u,u,p}\),换出去 \(x\),左子树换进去某个值,换出 \(w\),\(w\) 再换进右子树,在这里统计答案。
接下来考虑如何求 \(1\) 的答案。
- 只有左儿子。那么答案就是 \(\min(f_{y,w,q}+a_1q)\)。
- 有两个儿子,考虑左儿子边 - 右儿子边的转移,\(ans=\min(f_{y,w,q}+f_{z,v,q}+a_wp+a_1q)\),同样预处理 \(f1_w,f2_q\) 即可。
总时间复杂度 \(O(n^2)\)。
「NOIO #1」最小环 & 「LβR #3」绯色 IOI(开端)
很有趣的题目!考虑到后者的情况无非就是前者的 \(k=1\),这里只讨论前者怎么做。
注意到距离为 \(k\) 可以划分出 \(\gcd(n,k)\) 个环,距离不重要而环的个数是重要的,考虑如何分配这些环。
先考虑 \(k=1\) 的情况,此时只会被划分出一个环,我们希望两两相邻的乘积最大,则我们希望越大的数所匹配的值越大,根据这个可以构造出类似 \(\{2,4,6,5,3,1\}\) 的方案,也就是说每隔两个数算一遍贡献,特殊计算 \(a_n,a_{n-1}\) 和 \(a_1,a_2\) 的贡献。
环多的情况可以贪心的,连续的若干个数来填环,简单记忆化做到 \(O(nd(n))\)。
「CF17C」Balance
很难想到的一类 DP 方向?
考虑建出序列自动机,那么设 \(f_{i,a,b,c}\) 表示第 \(i\) 个位置有若干个对应字符。
则 DP 方法为 \(f_{i,a,b,c}\to f_{nxt_{i,1},a+1,b,c}\),理由是这样不会算重。
复杂度约为 \(O(n^4)\)。

浙公网安备 33010602011771号