CF1854A2

引领天下

2023-07-30 01:49:01

Solution

有趣的构造题。 **提示:本题的简单版本对困难版本有一定启发作用,推荐搭配 [A1 的题解](https://www.luogu.com.cn/blog/yltx/cf1854a1-post) 食用。** 题意: 给定一个长度为 $n$ 的序列,现在可以进行以下操作: - 选择 $i,j$(注意 $i$ 可以等于 $j$),将 $a_i\leftarrow a_i+a_j$。 做法: 我们注意到在做 A1 的 $a_n<0$ 的情况时,我们使用了一个很香的后缀和做法。 这个做法能否扩展呢? 显然是可以的。对于 $a_i$ 全负的情况,做后缀和即满足题意;对 $a_i$ 全正的情况,做前缀和即满足题意。 前缀和 和 后缀和 都需要 $n-1$ 次操作,于是问题就变成了如何在 $12$ 次内使 $a_i$ 全正或全负。 一个很自然的想法是用多的同化少的,即正的 $a_i$ 较多的时候就填平负的 $a_i$,否则填平正的。 以下以正的较多的情况展开讨论: 考虑这个做法什么时候会被卡到极限。 显然是正的 $a_i$ 的最大值(记为 $A$)远小于负的 $a_i$ 的最小值(记为 $B$),极限情况是 $A=1,B=-20$。 这种情况下我们想要让 $A>-B$ 需要 $5$ 次操作,这样一来留给我们填平负的 $a_i$ 的次数就只剩下了 $7$ 次。 那如果有 $8$ 个负数呢? 既然正的填负的超了,我们就考虑反过来负的填正的,这样的操作次数最多正好是 $20-8=12$ 次。 最后总次数刚好卡进 $31$ 次。~~妙的一笔~~ 对于 $A$ 更大或者 $B$ 更小的情况,讨论后即可发现正填负和负填正总有一种是正确的,详细的讨论过程与以上类似,这里就不展开了。 而负的 $a_i$ 较多的情况与正的较多的情况极为相似,此处同样不再赘述。 我的代码存在大量重复片段,这里就不贴出来了。 --- 题外话:有小天才上来看到 A1,A2 没有思路,于是去开 B ,吃了 5 发罚时,最后 82min 才过 B,然后 17min 切 A1,28min 切 A2。~~我觉得我能吹一年~~ 值得一提的是,这个小天才在求 $B$ 的时候是这么写的: ```cpp if(a[i]>0){ cnt[0]++; if(a[i]>mx)mx=a[i],mxi=i; }else{ cnt[1]++; if(a[i]<mn)mn=a[i],mni=i; } ``` 然后最小值求了个 0 出来,在 #2 TLE 了一次。 此处提醒大家以我为戒,注意符号,切勿再犯。