2024.4.28 近期练习

P6619 [省选联考 2020 A/B 卷] 冰火战士

对于一次战斗,冰火两方能量较少的那方会耗尽,答案为这个能量的两倍。
我们就是要找一个中间值,左边的冰战士能量值之和与右边火战士能量值之和最小值最大。
离散化,我们可以二分找到第一个冰的前缀和大于火的后缀和的位置 \(p\),答案为 \(p-1\)\(p\)
怎么二分呢,考虑线段树上二分,然而常数过大,改成树状数组上倍增。

P4899 [IOI2018] werewolf 狼人

对于每个询问,我们找到一个 \(x\),使得 \(s\to x\) 路径上最小值 \(> l\),且 \(x\to t\) 路径最大值 \(<r\).
一个路径上最大值最小值考虑用 kruskal 重构树。
我们发现 \(s\) 点和 \(t\) 点,各找到有一个子树的 \(x\) 满足条件,然后如何判断有无交集呢?
我们扫描线,枚举其中一棵树的子树,用树状数组维护另一棵树哪一些点在前一棵树的子树里。

P4690 [Ynoi2016] 镜中的昆虫

我们维护一个 \(pre\) 数组表示上一次出现的位置,对于 \([l,r]\) 的询问,就是一个二维数点。
具体地,用每个区间第一个出现的算贡献,也就是求 \(i\in[l,r],pre_i\in[1,l-1]\) 的个数。
先考虑单点修改怎么做,也就是加上时间维。变成三维偏序。
我们递推时间维,二维数点用 BIT 套线段树,或者使用 cdq 分治。
区间修改很麻烦,借鉴 ODT 树的思想,用 set 把同色的都合成一段。
原本有 \(n\) 个段,修改产生了 \(m\) 个段,修改的次数事实上是 \(O(n+m)\) 的。
我们对于一个段怎么修改呢,如果不是第一个元素,其它的前驱都是 \(i-1\),只要考虑第一个元素即可。
我们删除原有的段,也只用动第一个元素,其他的还是 \(i-1\)

P4314 CPU 监控

历史最值问题,考虑用线段树。维护 \(\begin{bmatrix}a \\b\end{bmatrix}\),表示当前值和历史最值。(使用广义矩乘)
区间加 \(k\) 也就是 \(\begin{bmatrix}a \\b\end{bmatrix}=\begin{bmatrix}k & -\infty\\k & 0\end{bmatrix}\times \begin{bmatrix}a \\b\end{bmatrix}\).
区间赋值的话,这个操作可以转化为区间加,暴力递归,根据颜色段均摊是 \(O(n)\).
然而我们还是用矩阵的话,就多加一维,维护 \(\begin{bmatrix}a \\b \\0\end{bmatrix}\),修改时 \(\begin{bmatrix}a \\b \\0\end{bmatrix} = \begin{bmatrix}-\infty & -\infty & k\\-\infty & 0 & k\\-\infty & -\infty & 0\end{bmatrix}\times \begin{bmatrix}a \\b \\0\end{bmatrix}\).
矩阵适合推导,不适合直接运算,我们维护非常数的位置,只有 \(4\) 个。
我们考虑两个矩阵相乘的时候发生什么,把这 \(4\) 个 tag 怎么算的从矩阵那推过来即可。

P6109 [Ynoi2009] rprmq1

由于是先修改再查询所以这是个二维的问题。
考虑弱化版,如果查询的矩阵从第一行开始,那么我们直接扫描线下来,维护历史最大值。
我们对于其中一维分治,考虑其中某一维跨过 \(mid\) 的答案,那么我们维护历史最大值即可。
我们要支持历史最大值的清空,打个清空标记即可。

P4767/P6246 [IOI2000] 邮局(加强版)

\(dp_{i,j}\) 表示前 \(i\) 个村庄放 \(j\) 个邮局的最小代价,转移 \(dp_{i,j}=\min(dp_{k,j-1}+w(k+1,i))\)
\(w(x,y)\) 表示 \([x,y]\) 里放一个邮局,使 \([x,y]\) 都到这个邮局的最小代价,邮局放中位数处即可。
然而 \(w(x,y)\) 是满足四边形不等式,所以 dp 满足决策单调性。
凭什么满足呢,\(w(x,y)=\sum_{i=x}^{(x+y)/2} (p_{(x+y)/2}-p_i)+\sum_{i=(x+y)/2+1}^y(p_i-p_{(x+y)/2})\).
\(w(x,y+1)=w(x,y)+p_{y+1}-p_{(x+y)/2}\),所以 \(w(x,y+1)+w(x-1,y)=2(x+y)+p_{y+1}-p_{x-1}\).
最后,\(w(x,y)+w(x-1,y+1)=2w(x,y)+p_y-p_x\)
显然 \(w(x,y+1)+w(x-1,y)\ge w(x,y)+w(x-1,y+1)\).
考虑加强版,感觉上是凸的,考虑用 wqs 二分把 \(k\) 给消掉,然后剩下的再来决策单调性。
但这个不能用分治了,因为是动态的,要二分队列。

P3734 [HAOI2017] 方案数

先考虑没有限制的点怎么做。我们枚举每个维走了多少步。
\(x\) 这维终点二进制 \(1\)\(s\) 位,走了 \(t\) 步,\(s\) 个有标号球放到 \(t\) 个有标号盒子,每个盒子至少一个球。
方案数是 \({s\brace t}t!\),最后我们把三个维合起来,多重集排列。
但是我们直接这么算,\(k\) 表示二进制位数,预处理就花了 \(O(k^6)\),我们可以给他降到 \(O(k^4)\).
事实上,设 \(f_{i,j,k}\) 表示方案数,枚举最后一步怎么走的,\(f_{i,j,k}=\sum C_i^tf_{t,j,k}+\sum C_j^tf_{i,t,k}+\sum C_k^t f_{i,j,t}\).
最后,有限制怎么办呢?考虑容斥。
每个点设 \(dp_i\) 表示 \(i\) 结尾的合法路径,转移容斥枚举第一个不合法。

P4229 某位歌姬的故事

注意到 \(n\) 大,\(q\) 小。这个题要先离散化,建议把区间左闭右开。
\(A=m_i=2\) 出发,也就是代表这个区间有 \(2\)。注意到若两个区间是包含的,里面那个有 \(2\) 即可。
所以我们设计一个 dp,设 \(dp_{i,j}\) 表示填到第 \(i\) 个区间,上一个放在第 \(j\) 个格子的方案数。\(O(m^2)\).
再到 \(A\) 没有限制的,根据区间的包含关系,若里面的区间比外面的大就无解了;
若是里面的更小,把里面的拎出来,外面的合起来;相等的最后再考虑。
最后,对于不同权值,形成了若干个不相交的段,每个权值来做 dp,因不相交故不同权值互不影响。
dp 的话同 \(A=2\),做贡献的话:若某段钦定有最大值 \(m\),其方案数为 \(m^{len}-(m-1)^{len}\).
具体地,我们可以从小到大加权值,用并查集维护当前还没删的段,每计算完一个权值就删掉。

P2490 [SDOI2011] 黑白棋

我们发现,相邻的白/黑就是一个 Nim 游戏。然而每次只能最多操作 \(d\) 个游戏的限制很麻烦。
这是 k-Nim 模型:把每堆石子数用二进制数表示,若把所有堆石子数二进制第 \(i\) 位的和表示为 \(r_i\)
当存在 \(r_i \bmod (k+1)\neq 0\),先手必胜;否则必败。
证明:若存在某个状态使得所有 \(r_i \bmod (k+1)=0\),操作一次后必不满足,因为 \(k+1>k\).
若存在 \(r_i\bmod (k+1)\neq 0\),必有一次操作使得所有 \(r_i \bmod (k+1)=0\),且操作数 \(<k+1\)
接下来我们 dp。我们计算先手必败的方案数,再用 \(C_n^k\) 减掉。
一开始 \(m\) 个堆每个堆都没有石子。设 \(dp_{i,j}\) 表示前 \(i\)\(r_i\) 模出来都是 \(0\),用了 \(j\) 个石子的方案数。
转移的话枚举 \(r_i\),然后把 \(r_i\) 放在 \(m\) 个盒子里。

posted @ 2024-04-28 22:17  GloriousCc  阅读(17)  评论(0编辑  收藏  举报