近期模拟赛题解与总结

内容大致包括(基本口胡的)每题题解、赛后总结、可能会有的周总结。

代码主要托管在 gitee 上面,直接粘上来太占空间了。

第一场模拟赛(2020.11.16)

第二场模拟赛(2020.11.18)

通过代码

比赛总结:

  • 进步:
    1. 第一第二题都解决了。
    2. 考试状态有所提升,受外界干扰的程度比较浅。
    3. 有了打草稿,写思路,规划时间的意识。
  • 有待改进:
    1. 第二题调试耗时太长,导致后面的题目基本没有时间思考。因此要加快基础题的解决速度,提高准确度
    2. 写骗分的时候要提高准确度,不然也是白搭。
    3. 提高乱搞能力今天 T3 数据难造,于是许多人就水过去了 qwq 。

T1:剪头发

原题:[USACO2020Open]Haircut G

签到题,从小到大枚举 \(j\) 。此时有逆序对 \((x,y)\) ,那么必然有 \(A_y<j\) 。因此我们可以在 \(j=A_i\) 的时候加入 \(A_i\) 作为后面一个数产生的逆序对。时间是 \(O(n\log_2n)\)

T2: T 形覆盖

原题:[eJOI2019]T形覆盖

这不 T2 吗怎么都紫了

首先发现,只有 Manhattan 距离 \(\le 2\) 的关键点才会互相影响。于是,我们可以将这样的关键点联系起来。

对于一堆连通的关键点,我们考虑它们合不合法。统计它们周围白格子(也即没有关键点的格子)。只要可用格子数量不小于需要的格子,那么就一定可以拼凑出来。

更进一步的,我们考虑最初的一个关键点,它有 \(4\) 个白格。现在加入一个,如果与它有公共边,那么就相当于增加了 \(2\) 个白格——因而如果要保证足够的白格,最多只有两个有公共边的白格

如果没有公共边,那么就相当于增加了 \(3\) 个白格。于是,如果我们最终有 \(n\) 个连通的关键点,我们至多有 \(3n+1\) 个白格。如果白格 \(< 3n\) ,那么就 GG 了;否则,我们就考虑选取所有白格( \(3n\) 个),或者丢掉最小的一个。

T3: 迷途竹林

原题:[CF505E]Mr. Kitayuta vs. Bamboos

(准备写成单独的题解)

考虑二分答案,当前的答案为 \(L\) 。设第 \(i\) 棵竹子在第 \(j\) 天被砍了 \(c_{i,j}\) 次,那么合法的情况应该是:

\[\max\{h_i+ma_i-p\sum_{j=1}^mc_{i,j},\max_{j=1}^m\{(m+j-1)a_i-\sum_{k=j+1}^mc_{i,k}\}\}\le L \]

其中第一层 \(\max\) 的前面部分表示的是 " 中途不被切没 " 的情况,后半部分枚举最后一次切没是什么时候,然后计算出最后剩余的高度。这里我们认为高度可以变为负数,因为枚举使得它不再重要。

以此我们可以得到 \(c_i\) 的后缀和 \(s_i\) 对于每一个 \(j\) 的下界。现在直接做是 \(O(nm\log_2W)\) 的。

但是,请注意总切的次数为 \(mk\) ,而我们现在的时间是 \(O(\max\{nm,mk\})\) ,我们需要将它优化为 \(O(\min\{nm,mk\})\) ,即,我们需要每次都在必须得切的时候再计算。前面我们可以得到:

\[(m-j+1)a_i-ps_{i,j}\le L \]

\(s_{i,j}+1\) 代入计算即可得到下一次必须得切的时候。对于每个节点,我们可以用一个队列维护哪些竹子在当前点必须被切掉,并用一个变量记录当前剩多少次操作机会(这个机会下一次还可以用,毕竟是允许负数高度的)。时间是 \(O(mk\log_2W)\)

T4: 游戏

原题:[HDU6829]Borrow

(准备写成单独题解)

首先考虑三维的 DP 。然后发现只有值的相对关系才重要,因此用差值做状态。

\(z\) 为最大值,那么考虑 \(f(a,b)\) 表示 \(z-x=a,z-y=b\) 的时候的期望。这里我们并不要求 \(x,y\) 的相对关系,因为我们可以对调再计算

考虑转移:

\[f(a,b)=\begin{cases}\frac{1}{2}f(a-1,b-2)+\frac{1}{2}f(a-2,b-1)+1&a,b\ge 2\\\frac{1}{2}f(1,b-1)+\frac{1}{2}f(2,b+1)+1&a=0\\\frac{1}{2}f(a-1,1)+\frac{1}{2}f(a+1,2)+1&b=0\\\frac{1}{2}f(0,b+1)+\frac{1}{2}f(1,b)+1&a=1\\\frac{1}{2}f(a+1,0)+\frac{1}{2}f(a,1)+1&b=1\\\end{cases} \]

然后发现只有 \(a\le 2\)\(b\le 2\) 的时候有环,手解可以得出,合法情况下有:

\[\begin{aligned}f(1,b)&=2+4\times \lfloor\frac b 3\rfloor\\f(0,b)&=f(1,b-1)+2=4\times \lfloor\frac b 3\rfloor\end{aligned} \]

另一边基本同理。此时如果做 \(O(n^2)\) 的递推即可得到 70 pts 。

考虑优化。对于存在边界的期望,我们可以尝试直接计算边界的贡献。也就是,对于 \(f(0)\)\(f(1)\) ,我们用概率乘以贡献。注意到 \(f(a,b)\) 的状态,走到边界的过程中,始终走的是 " 日 " 字。因此我们可以解出走的正 " 日 " 的次数 \(p\) 和倒 " 日 " 的次数 \(q\) 。那么走到的概率可以方便地计算。贡献注意加上额外的步数(我们枚举了所有的终点,因此不需要考虑中途贡献系数不同的情况,重复计算帮助我们解决了这个问题)。额外需要注意的是,\(f(0)\) 的方案不能计算经过了 \(f(1)\) 的方案,减去即可。

时间是 \(O(n)\)

第七场模拟赛题解

通过代码

比赛总结:

  • 进步:
    • T1、T2 的解决速度比较快。
    • 我会乱搞骗分了。 T3 成功通过乱搞做法骗到分。
  • 有待改进:
    • 做 T3、T4 的时候状态明显下滑了,注意不集中,思考时间太长、写的时间很短而收益很低。下次可以尝试给每道题限定 30min 的思考时间,如果不是感觉方向基本正确就先开始写代码。中途要注意适度休息,多上几次厕所,说不定就可以想到新思路,或者突然就想通了。
    • T4 骗分也挂掉了,准确度还是不够高,不能总是依赖对拍。
    • 思路要更发散一些。 T3 明明已经到正解边缘了,还是没想到。

T1:bins

原题:[BalticOI 2010 Day2] Matching Bins

简单题,枚举 \(K\) ,把两段值分别丢到桶里。检查直接从大到小扫一遍,看是否有放不下的即可。

时间是 \(O(nm)\)

T2:inversions

原题:[CF414C]Mashmokh and Reverse Operation

简单题。一次交换操作会让所有跨越 \(2^k(k<q)\) 的段的顺序对变成逆序对,逆序对变成顺序对,于是对同一种段打标记,每次询问后直接统计。于是我们只需要考虑长度为 \(2^k\) 的段的跨越中点的顺序对和逆序对,归并排序预处理。

时间是 \(O((2^n+m)n)\)

T3:candies

原题:[BalticOI 2010 Day2] Candies

稍微难一些的题目。

\(P\) 非常简单。我们可以直接背包求出包含所有值的组合情况,接着枚举一个 \(B\) ,我们将它从可选集合中删去,也就是 \(O(nB)\) 的退背包。那么考虑当 \(Q\) 充分大的时候,我们的组合情况数可以直接翻倍。于是我们就求出删去后组合情况数最大的一个 \(B\) 作为我们的 \(P\) 即可。

接着考虑 \(Q\) ,可以发现一个 \(Q\) 合法的条件是,\(\forall S\subset U,\not\exist T\subset U,\sum_{u\in S}u+Q=\sum_{u\in T}u\)\(U\) 为全集去掉 \(P\) ),那么移项得到 \(Q=\sum_{u\in T}u-\sum_{v\in S}v\) 。可以发现这也是背包的形式,只不过符号有正有负。并且我们最终只需要知道某个值能不能凑出来,因此可以 bitset 优化。

时间是 \(O(n^2B)\)

考场的乱搞做法:

注意到最终的值域很小,只有 \(7\times 10^5\) ,而方案数是指数级别的,因此可能会有很多个可以凑出的数连在一起。我们可以将连起来的一段一起判断,而不需要拆开。退背包之后,处理每个位置向后的连续的 0 的个数和值非 0 的段,之后我们就可以枚举 \(Q\) 并进行判断。

贪心地想,我们应该将较长的段优先判断,而从小到大枚举保证了它可以在找到第一个可行值之后退出,因此它在随机数据下表现良好。

事实上,它不仅能过官方数据,还跑得飞快

T4:sheep

题目简述:

给定一棵大小为 \(n\) 的树,树上有 \(k\) 只 🐑 。如果在 \(u\) 上安排一位牧羊人,那么他会守卫最近的 🐑 不被吃掉(如果有多头就一起守卫)。求最少需要安排多少为牧羊人。

数据范围: \(1\le k\le n\le 5\times 10^5\)

这道题跟 [POI2011]DYN-Dynamite 有点相似。

首先可以预处理,得到 \(d_u\) ,表示 \(u\) 能覆盖的距离。

我们考虑在树上由叶子到根进行贪心。处理完一棵子树之后,我们得到了两个信息:该子树内所有未被覆盖的 🐑 的深度(可以发现不可能有深度不同的两只 🐑 ),以及子树内牧羊人超过根的最广覆盖范围。合并一颗子树,我们可以用当前树的牧羊人覆盖新子树,也可以用新子树的牧羊人覆盖当前子树,并更新当前树的两个信息。

合并完成之后,我们就需要考虑当前子树的根是否应该安排牧羊人。如果 \(d_{fa}>d_u\) ,那么必然有 \(d_{fa}=d_u+1\) 。此时如果放置在 \(fa\) 上面,那么同样能覆盖当前子树,并且更优,于是我们就推迟操作;反过来,我们在当前点上安排牧羊人。这也保证了不会有不同深度的 🐑 。

时间复杂度是 \(O(n)\)

第八场模拟赛(2020.11.30)

比赛总结:

  • 进步:
    • 仍然是简单题比较稳健,没有出锅。
    • 面对今天的一组比较难的题,心里已经没有那么慌张了,证明心理素质在提高。
  • 有待改进:
    • T4 没想好就开始写,不仅是不熟悉的内容,而且写完了才发现自己伪了,浪费时间,结果半分没多骗到。
    • T3 完全没有思路,然而骗分并不难,概率期望板块还是很弱。
    • T1、T2 花费时间偏长,而且 T2 的时间基本都在打水漂; T3、T4 时间规划基本没有,因为心里觉得 T4 能行,所以 T3 基本就弃掉了,但是事实证明 T3 相对来说更容易骗分。一定严格按照时间来考

第十场模拟赛(2020.12.02)

通过代码

比赛总结:

  • 进步:
    • 解决了一道计数题目虽然我觉得挺简单的
    • T3 骗分看起来写得不错
    • 遇到后面题目比较难,保证了心态没有崩掉,按照安排做题
  • 有待改进:
    • T2 被卡常了呀 qwq
    • T4 明明可以打表多得 30 pts ,偏偏没有想到这一点。
    • 如果之后再遇到今天这种不太简单的比赛,尽量先把每道题的暴力先写好

T1: bricks

原题:[CF1355E]Restorer Distance

简单题目,可以发现函数可以直接三分。

或者发现在每一段内,函数最多由两段一次函数拼起来,所以可以在每个分界点计算答案。

T2: rgbgraph

原题:「美团 CodeM 初赛 Round A」二分图染色

可以想到直接计算红和蓝的方案,但是会算重,可以容斥:

\[\sum_{k=0}^n(-1)^kk!\binom{n}{k}^2\left(\sum_{i=0}^{n-k}i!\binom{n-k}{i}^2\right)^2 \]

现在是 \(O(n^2)\) 。注意后面的那一部分等价于求一个完全二部图内任意匹配的方案数,可以直接递推。设 \(f_n\) 为一个左右大小均为 \(n\) 的完全二部图任意匹配的方案数,考虑新加入的两个点的匹配边可以得到:

\[f_n=f_{n-1}+(2n-1)f_{n-1}+(n-1)^2f_{n-2} \]

现在就可以 \(O(n)\) 解决问题了。

T3: cyclesort

原题:「eJOI2018」循环排序

首先可以发现,原图总可以被拆分成许多环。观察样例可以发现,我们可以用一次操作合并 \(n\) 个环,再用一次操作解决这个大环,仅仅带来 \(n\) 的多余操作下标。

现在问题在于,如何确定环该如何拆分?贪心地想,我们显然应该尽量拆分更少的环。对于多个值相同的点,我们可以将它们全部连到一个虚点上,再从虚点连向最后的可行位置。那么此时原先的一个环仍然是一个环,现在环尽量少等价于一个环尽量大再次观察样例可以猜想是取欧拉路。所以按照这个意思跑欧拉路模拟即可。

输出方案可以直接构造,不再赘述。

T4: parentrises

原题:「BalkanOI 2018 Day2」Parentrises

考场上只有阉割版,也就是 \(P=2\) 的情况。

可以发现,此时必然是一个失配的括号可以和一个匹配的相同括号相配,两个染不同颜色,那么在隐藏了某种颜色之后仍然是良括号串。

换种想法,我们认为一个括号现在可以匹配上两个括号。也就是说,在从左往右做匹配的时候,我们认为一个右括号可以最多匹配两个左括号;从右往左,一个左括号最多可以匹配两个右括号。

经过转化,现在问题就简单了,可以直接设:

\(f(i,j,k)\):前 \(i\) 个字符确定后,前缀和为 \(j\) ,最小后缀和为 \(k\) 的方案数。

转移直接枚举当前括号。注意滚动数组优化空间。时间复杂度是 \(O(n^3)\)

posted @ 2020-11-18 21:03  crashed  阅读(173)  评论(0编辑  收藏  举报