其他分享
首页 > 其他分享> > IOI 2022 题解 & 锐评

IOI 2022 题解 & 锐评

作者:互联网

IOI 2022 D1T1 Fish

题目大意:

有一个 \(N\times N\) 的网格,其中的 \(M\) 个位置有垒球,第 \(i\) 个垒球的位置为 \((x_i,y_i)\),重量为 \(w_i\)。

你可以为每一列 \(c\) 选择一个前缀的行 \(1,2,\ldots,\ldots,r_c\) 修建长堤,这样 \((1,c),(2,c),\ldots,(r_c,c)\) 这些位置就会被长堤覆盖。

如果一个垒球的位置没有被长堤覆盖,且其左右相邻的位置至少有一个被长堤覆盖,那么就会有一个 ix35 走到长堤上捡起这个垒球,即如果垒球的位置为 \((x,y)\),它能被捡起当且仅当 \((x,y)\) 未被长堤覆盖且 \((x,y-1),(x,y+1)\) 至少有一个被长堤覆盖。

求最多能捡起总重多少的垒球。

\(N\leq 10^5,\ M\leq 3\times 10^5\)


题解:

假设 \(r_{c-1}<r_c>r_{c+1}\),那么第 \(c\) 列的垒球都不能被捡起,所以不如直接把第 \(c\) 列修到顶,即 \(r_c\) 可以改为 \(N\)。

假设 \(r_{c-1}>r_c<r_{c+1}\),那么第 \(c\) 列不如不修,所以 \(r_c\) 可以改为 \(0\)。

于是我们观察长堤的形状,发现修建了长堤的列可以分成若干连续段,每一段内 \(r_c\) 先递增后递减。

据此容易写出 DP,时间复杂度为 \(O(M\log M+N)\)。

IOI 2022 D1T2 Prison

题目大意:

有 \(500\) 个囚犯,还有一个房间,房间中有两个袋子 \(A,B\),分别装有 \(n_A,n_B\) 个垒球,此外还有一个数字 \(x\),初始为 \(0\)。囚犯们已知 \(1\leq n_A,n_B\leq N\) 且 \(n_A\ne n_B\),他们的目标是指出 \(n_A\) 和 \(n_B\) 的大小关系。

现在会按照随机的顺序每次叫一个囚犯进房间,此时囚犯可以看到数字 \(x\),并做出两种选择之一:打开袋子 \(A\),或者打开袋子 \(B\),即获知 \(n_A\) 或 \(n_B\)。

此时囚犯知道了 \(x\) 以及一个袋子中的垒球数量,他可以做出三种选择之一:指出 \(n_A<n_B\),或者指出 \(n_B<n_A\),或者将 \(x\) 修改为 \(x'\)(也可以 \(x'=x\))。

你需要构造一种策略,使得任意时刻 \(0\leq x\leq X\),且在 \(500\) 个囚犯都进去过一次之前得到 \(n_A,n_B\) 的大小关系。

\(N\leq 5000\),当你构造的 \(X\) 满足 \(X\leq 20\) 时得满分。


题解:

这里写的就是我的思考过程。

首先考虑一个最最 naive 的方法:考虑 \(n_A,n_B\) 的二进制表示,前两个人比较 \(n_A,n_B\) 的最高位,第三个和第四个人比较 \(n_A,n_B\) 的次高位,以此类推,那么可以实现如下:

这样需要 \(X=38\) 左右。

我们将这方法略作修改,如果第 \(2\) 个人进来看到 \(n_A,n_B\) 最高位相同,并不是只能把 \(x\) 改成 \(3\) 然后交给下一个人,实际上他还掌握更多信息,比如 \(n_B\) 的次高位,于是我们将策略改成如下:

这样只需要 \(2\log N\) 次,即 \(X=26\)。

再优化一下,发现这里采用二进制不如采用三进制,\(3^8>N\),所以只需要 \(X=3\times 8=24\) 即可。

再想一想,其实对于不同的数据范围可以采用不同的进制,于是我们考虑 DP,令 \(f(i)\) 表示 \(N=i\) 需要的最小的 \(X\),枚举将 \(i\) 分成 \(j\) 段,那么 \(f(i)\leftarrow f(\lceil\dfrac{i}{j}\rceil)+j\),这样应该可以 \(X=22\) 或者 \(X=21\)。

现在只需要卡一下常数就可以了,我们注意到如果第一个人进去发现 \(n_A=1\) 或者 \(n_A=N\) 都可以直接返回结果(因为保证 \(n_A\ne n_B\)),所以我们每次可以把边上两个数砍掉,于是转移变成 \(f(i)\leftarrow f(\lceil\dfrac{i-2}{j}\rceil)+j\),这样就能顺利得到 \(X=20\) 的解。

IOI 2022 D1T3 Towers

题目大意:

有 \(N\) 座塔,第 \(i\) 座塔高度为 \(h_i\),保证高度两两不同。

现在有 \(Q\) 个询问,每个询问给定 \(l,r,d\),询问从 \([l,r]\) 中至多可以选择多少个塔,使得他们两两可以 \(d\)-通信。

两座塔 \(i<j\) 可以 \(d\)-通信,当且仅当存在一座塔 \(k\) 使得 \(i<k<j\) 且 \(h_k-d\ge\max(h_i,h_j)\)。

垒球。

\(N,Q\leq 10^5\)。


题解:

对于一个确定的 \(d\),令 \(l_i\) 表示 \(i\) 左边第一个比 \(i\) 高了至少 \(d\) 的位置,\(r_i\) 表示 \(i\) 右边第一个比 \(i\) 高了至少 \(d\) 的位置。

那么两座塔 \(i<j\) 能 \(d\)-通信,当且仅当 \(r_i\leq l_j\),即它们对应的区间 \([l_i,r_i)\) 无交。

同时易证以下两个结论:

于是我们可以从小到大扫描 \(d\),维护当前没有包含任何其他 \([l_j,r_j)\) 的区间 \([l_i,r_i)\),根据第一个结论,它们是两两无交的。我们称这些区间为 \(d\) 对应的有效区间。

扫描过程中维护的方法是:用一个链表记录当前的有效区间,并且用优先队列记录每个区间在什么时间(即 \(d\) 增大到多少时)会和左边或右边合并,然后在合并时删去一个元素即可。由于询问在线,所以需要用主席树记录每个时刻的有效区间。

询问 \((L,R,d)\) 时,我们首先找到这个 \(d\) 对应的情况下,\([L,R]\) 中有多少个有效区间(一个有效区间 \([l_i,r_i)\) 在 \([L,R]\) 中定义为其中心点 \(i\) 在 \([L,R]\) 中)。

那么这些有效区间的中心一定是要选择的了,但是可能还不全面,因为左右两边可能还需要各补选 \(0\) 个或 \(1\) 个塔(这是因为可能某个有效区间与 \([L,R]\) 有交,但是其中心不在 \([L,R]\) 中,就没统计到)。

这个稍微讨论一下即可:

用 ST 表预处理区间最值。

时间复杂度为 \(O((N+Q)\log N)\)。

IOI 2022 D2T1 Circuit

题目大意:

给定一个 \(N\) 个非叶结点,\(M\) 个叶结点的值,叶结点有初值 \(0\) 或 \(1\),某个非叶结点如果有 \(x\) 个儿子,则需要设置一个参数 \(y\in [1,x]\),表示如果其儿子有至少 \(y\) 个的值为 \(1\),那么它的值也为 \(1\)。

现在进行 \(Q\) 次操作,每次翻转编号在区间 \([l,r]\) 内的叶结点的初值(\(0\) 变成 \(1\),\(1\) 变成 \(0\)),然后询问有多少种为非叶结点设置参数的方案,使得根结点值为 \(1\),对 \(10^9+2022\) 取模。

\(N,M,Q\leq 10^5\)


题解:

如果你是赛后做题,那么解题的关键或许是看到排行榜——有一车人过了这题,说明这题是水题。

或者是觉得这题看上去非常不可做,因为编号区间和树的形态并无关联,我们不可能用任何树上的数据解构解决此题。

无论如何,我们可以猜想:每个非叶结点对答案的贡献独立,幸运的是这是对的,证明并不困难,略。

于是首先树形 DP 算出每个非叶结点单独为黑色时的答案,然后用线段树维护总的答案即可,时间复杂度为 \(O(Q\log M+N+M)\)。

IOI 2022 D2T2 Insects

题目大意:

现在有 \(N\) 个未知数 \(a_{1\ldots n}\),还有一台神秘机器,机器初始是空的,你可以进行下列三种操作:

你需要求出 \(a_{1\ldots n}\) 中出现次数最少的数的出现次数,设每种操作进行次数的最大值为 \(Q\)。

\(N\leq 2000\),\(Q\leq 3N\) 可得满分。


题解:

首先可以想到一个 \(O(N^2)\) 次操作的算法:每次放一对数进去,就能知道它们是否相等。

还有一种 \(O(N^2)\) 次操作的算法(记为青蛙算法):每次选择一个数,然后得到与它相等的所有数(加入一个别的数如果众数出现次数没有增加则说明不相等)。

还有一种 \(O(N^2)\) 次操作的算法(记为垒球算法):每次选择当前剩下的所有不同的数各一个(时刻保持众数出现次数为 \(1\) 即可),这样当某一次得到的不同的数的个数和上一次不同时,就知道出现次数最少的已经取完了。

综合青蛙算法和垒球算法,可以得到 \(O(N\sqrt N)\) 的算法。

考虑垒球算法的扩展:如果保持众数出现次数始终小于等于 \(C\),就可以得到每个数的前 \(C\) 次出现,设不同的数有 \(x\) 种,如果选出了恰好 \(Cx\) 个数则说明出现次数最少的数也出现了 \(\ge C\) 次,否则说明是 \(<C\) 次。

所以可以二分,得到了 \(O(N\log N)\) 的垒球算法。

然后发现这个二分的操作次数实际上可以变成 \(O(N)\),因为如果二分之后发现答案 \(\ge C\),那么此时已经放进机器里的就不用动了,可以看成总数大致减半;如果二分之后答案 \(<C\),那么此刻不在机器里的数就可以全部扔掉了,总数也大致减半,根据等比数列求和这就是 \(3N\) 次左右的。

然后一交获得了 \(99\) 分的好成绩,下面使用你的独门技巧乱搞卡常即可。这里我的方法是在判断时只要某个时刻机器里已经有 \(Cx\) 个数就直接退出循环,没必要加剩下的数,同时为了防卡,初始序列要随机重排。

IOI 2022 D2T3 Islands

题目大意:

有一张 \(N\) 个点,\(M\) 条边的有向图,你需要从点 \(1\) 出发走一些边回到点 \(1\),要求:

构造一组方案,或说明无解。

\(N\leq 10^5,\ M\leq 2\times 10^5\)


题解:

如果一个结点出度为 \(0\),那么走到这里就寄了,所以可以删掉。

删掉之后可能会导致另一些点出度也变为 \(0\),也要删掉,这个可以做一次拓扑排序,就相当于我们删掉了所有不能走到环的点。

现在我们断言,如果点 \(1\) 的出度 \(\ge 2\),那么一定有解,下面给出构造。

事实上考虑下列结构:由于不存在零出度点,所以我们可以为每个点(除了 \(1\))指定一条出边,这样整张图就形成了若干个基环树,以及一棵以 \(1\) 为根的树,如下图所示:

现在我们加上 \(1\) 的两条出边,那么有以下两种情况:

那么 \(1\) 的出度 \(\ge 2\) 的情况已经证完了,下面考虑 \(1\) 的出度 \(=1\) 的情况。

这时我们只能走这条出边,设为 \(1\to x\),之后 \(1\) 就可以看出零出度点(只要在不走 \(x\to 1\) 这条反向边的情况下回到 \(1\) 就寄了),所以我们删去点 \(1\),同样这也会导致连锁反应,还是用一个拓扑排序就可以把所有该删的点都删了。

在剩下的新图上,把 \(x\) 看成起点继续做即可,即如果 \(x\) 的出度 \(\ge 2\) 那么按照上面方法得到构造;如果 \(x\) 的出度 \(=1\) 那么再走它的出边,然后把 \(x\) 删掉,以此类推。

时间复杂度应该可以做到 \(O(N+M)\),不过我在实现时为了图省事,在记录边的序号以及删点的时候用到了 multisetmap,复杂度为 \(O(N+M\log M)\)。


锐评环节

D1T1:比较简单的题,大概是想到单调性之后随便 DP 一下就行了,不过如果没想明白的话可能会用线段树去维护,其实是不用的。

D1T2:人类智慧题,有点看运气,运气好就想出来罢了,主要是到 \(X=26\) 那一步比较有难度,后面的使用其他进制并 DP 以及掐头去尾其实都不是很难。

D1T3:偏简单题,主要是想到用区间表示每个点的状态,后面的数据结构部分非常简单。

D2T1:诈骗题,猜出结论就没有难度了,而想到去猜这个结论其实并不很难(正如我前面所说,如果没有这种结论,这题是不可做的)。

D2T2:中档题,每一步优化都不是很难,但是只要少一步就做不出来,然后最后还要为了零点零几分在那卡常。

D2T3:思维简单,代码不太好写题,感觉这题口胡起来非常舒服。

标签:结点,2022,题解,可以,leq,如果,IOI,垒球,区间
来源: https://www.cnblogs.com/ix35/p/16582891.html