随机乱做 Part 2

「WC2016」论战捆竹竿(利用 border 的性质优化同余最短路)

题面

首先可以暴力求出所有 \(\bf{border}\),然后暴力跑同余最短路。即使用 \(n-|\bf{border}|\) 能拼出多少个 \([n,m]\) 之间的数。

一个关键性质:所有 \(\bf{border}\) 形成了 \(\mathcal{O}(\log n)\) 个等差数列。

记录 \(f_i\) 表示在当前模数下要使得 \(\bmod mod=i\) 要加的最小数。

那么我们考虑依次加入等差数列。

剩下的懒得写了,见洛谷题解区。

代码:https://pastebin.ubuntu.com/p/GFv9JYrtX4/

「WC2010」重建计划(01 分数规划 + 点分治 + 单调队列)

题面

很明显可以用 01 分数规划的套路进行二分,然后每条边的权值减去一个数,求有没有长度在 \(L\sim U\) 之间的和为 \(0\) 的链。

对于路径问题肯定先考虑点分治,然后合并路径的时候可以单调队列。

因为卡常,所以需要把点分树提前建出来,不需要每次重新找重心。

代码:https://pastebin.ubuntu.com/p/DMrzvKFptY/

「CF1733E」Conveyor(递推)

题意:

给定一个 \(120 \times 120\) 的表格 \((0 − based)\),每个格子上有一个传送带,可以将史莱姆向右或向下传送一格,之后这个传送带的方向立刻发生变化,即向右变向下,向下变向右。

如果两个史莱姆撞上了,它们就会融合。如果一个史莱姆(向右或向下)走出了表格,那它确实就走出了表格。

初始的时候所有传送带们都向右,随后每一秒我们都在 \((0, 0)\) 放置一个新的史莱姆。

\(q\le 10^5\) 次询问,每次问在第 \(t(t \le 10^{18})\) 秒,\((x,y)\) 这个格子上是否有史莱姆。

首先,史莱姆肯定不会融合,因为每一个走过的距离都不一样。

那么我们可以考虑通过第 \(t\) 秒与第 \(t-1\) 秒时 \((x,y)\) 上的史莱姆个数是否相同来判断。

对于这个,可以递推:即先在 \(a_{0,0}\) 上放置 \(\max(0,t-x-y+1)\) 个史莱姆(因为在这之后放的都不可能到达 \((x,y)\)),\((i,j)\) 向右边会移动 \(\lceil\frac{a_{i,j}}{2}\rceil\) 个史莱姆,向下会移动 \(\lfloor\frac{a_{i,j}}{2}\rfloor\) 个。

代码:https://pastebin.ubuntu.com/p/337QRbS3v9/

「CF1612G」Max Sum Array(差分 + 贪心)

题面

如果位置 \(x\) 上放的是从前往后第 \(j\) 个值为 \(i\) 的数,那么它对答案的贡献就是 \((2j-c_i-1)x\)

很明显如果我们可以把所有的 \((2j-c_i-1)\) 拿出来然后从小到大排序依次填入,答案肯定是最大的。证明可以由排序不等式推出。

然而时间上不允许,所以我们可以考虑差分。一个 \(i\) 能贡献的范围是 \(1-c_i,3-c_i,\dots,c_i-3,c_i-1\),即一个公差为 \(2\) 的等差数列,放的时候就等差数列直接算和,因为它们的系数都是一样的。

求方案的话可以发现系数一样的可以随便排,就是 \(\prod cnt_j\)

注意开 LL!!!!

代码:https://pastebin.ubuntu.com/p/NnfF5xh7zp/

「ABC270G」Sequence in mod P(BSGS)

题面

把答案的式子写出来,其实就是要求满足 \(A^iS+A^{i-1}B+A^{i-2}B+\cdots+AB+B\equiv G\pmod P\) 的最小的 \(i\)

\(B=0\) 的时候就是 BSGS 模板,考虑在加入了 \(B\) 之后还是按照一样的套路,设阈值 \(M=\sqrt P\),然后预处理 \(0\sim M\) 的值存入哈希表,其它的暴力每次跳 \(M\) 的大小。

那么最后的式子也就形如:

\[(A^xS+A^{x-1}B+\cdots+AB+B)A^{y-x}+A^{y-x-1}B+A^{y-x-2}B+\cdots+AB+B\equiv G\pmod P \]

其中 \(x\) 是某个 \(M\) 的倍数。

移项后可得:

\[A^xS+A^{x-1}B+\cdots+AB+B\equiv G\times\frac{1}{A^{y-x}}-B\times(\frac{1}{A}+\cdots+\frac{1}{A^{y-x}}) \]

这样我们的思路就很明了了!

左右都可以递推得出来!

代码:https://pastebin.ubuntu.com/p/9Ctt5wdZZ4/

「洛谷 P8552」Rabbit(并查集 + 逆向思维)

题面

一个很显然的做法是,对于每一个点 \(x\),考虑它的子树,如果有 \(\ge 2\) 个儿子的子树内有没有被选过的点,那么就把它们和 \(x\) 标记上,并且答案 \(+1\),可惜这是 \(n^2\) 的。

考虑逆向思维,从小到大枚举点权,把一个点和它周围点权比它小的点全部并起来,记录一下每个连通块里还没有被匹配的点数。如果并完之后有 \(\ge 3\) 个未匹配的就匹配它们。

代码:https://pastebin.ubuntu.com/p/RbKt36SRT3/

「CF1527E」Partition Game(分治决策单调性 + 指针暴跳)

题面

直接暴力 dp 很显然,把式子写出来感性理解发现具有决策单调性。

分层转移的问题一般要长个心眼,想想有没有决策单调性。

莫队状指针移动可以考虑分治决策单调性!

然后套用 这里边 的分治决策单调性即可。

代码:https://pastebin.ubuntu.com/p/gkmkWFtp6v/

「CF1430G」Yet Another DAG Problem(状压 dp)

题面

很容易想到分层标号。

数据范围很小,考虑状压。

关键一步:把连接层数不相邻的边的贡献拆到每一层里计算。

然后就可以很好地状压 dp 了。设 \(f_S\) 表示已经选了前面若干层的节点集合是 \(S\),那么可以枚举子集转移所有可能的下一层节点(条件是下一层节点的入点都在 \(S\) 中),贡献就是起点在 \(S\) 中、终点不在的所有边的权值之和。

方案也很好输出,记录每个状态从哪里转移过来即可。

代码:https://pastebin.ubuntu.com/p/PG4SYYvTTx/

「CF1611G」Robot and Candies(贪心 + set)

题面

神仙贪心.jpg

容易发现一次操作会使 \(x\leftarrow x+1\) 并且 \(x+y\leftarrow x+y\) 或者 \(x+y\leftarrow x+y+2\)。所以 \(x+y\) 的奇偶性不会发生变化,可以分奇偶考虑。

将所有 1 放到坐标系上考虑,其中 \(x\) 轴是行,\(y\) 轴是行 + 列,即原矩形中的 \(x+y\)

那么一次操作要么向右走 \(1\) 单位,要么向上走 \(2\) 单位且向右走 \(1\) 单位。

如果走出去了,我们就按边界对称过来。

重要结论:按照横坐标扫过去,如果这一行的后面还有点,就继续把这一行删完;否则将纵坐标 \(+2\) 继续操作。

证明可以考虑调整。

那么直接维护每一个纵坐标对应横坐标的集合 set,模拟这个过程就行了。

实现上注意我们只需要考虑有点的纵坐标。

代码:https://pastebin.ubuntu.com/p/p8GXCZ7B6p/

「CF1675G」Sorting Pancakes(DP)

题面

把问题放在前缀和序列上来考虑,手玩之后可以发现:操作一次就是其前缀和序列变化了 \(1\)

那么可以设 \(f_{i,j,k}\) 表示前 \(i\) 个数,最后一个数为 \(j\),和为 \(k\) 的最小操作次数。直接枚举下一个选什么就行,贡献为 \(|k+nxt-sum_{i+1}|\)

代码:https://pastebin.ubuntu.com/p/dJ86rM7MrV/

posted @ 2022-09-27 16:25  csxsi  阅读(48)  评论(0编辑  收藏  举报