【题解】ace5 and Task Order - Codeforces 1918E

原题链接:https://codeforces.com/problemset/problem/1918/E

交互题,有一点点复杂,我想了很久,而且也是我好多年没有完全自己去挑战一个2200的题了,平时不是看别人的答案就是看题解。最后,我用了一种和官方答案写法有区别的做法,可能我觉得有必要来记录一下。

首先这个题目的限制是40n,也就是说每个元素平均有40次机会。这个看起来像二分,但是数据量只有1000,所以我不知道这个多出来的4倍是干嘛的。

首先想着是不是猜出x就好了,但是我写到一半发现哪怕返回=号也不能确定x的值。

然后很自然的就是用一个办法,通过记录最后一个相等的位置,去让x保持单调递增或者单调递减,大概用2n次(以把x单调递增到n为例,无论x是多少,都是从i=1一直问到i=n,因为每个元素至少会被问1次,如果是a[i]>x,那么不断询问同一个i直到其=x,如果是a[i]=x就跳过,如果是a[i]<x就寻找最后一个=x的位置对x进行复原,复原操作只有1次,而递增的操作由势能可知均摊1次,所以应该是2n次?)(还是3*n次)就可以把x推到1和推到n(这里和官方题解一样),同时记录到的最后一个相等的位置就是1和n的位置了。

官方题解说,知道了1和n的位置之后,那么每次取x=n/2,然后把每个元素分成左右两堆递归下去就可以了。

我用的方法其实是倒转过来的,我求的是每个元素可能得区间L[i], R[i],然后算出这个区间的中点M[i],对中点M[i]进行排序。然后让x保持单调递增和单调递减轮流不断去扫这个中点数组,比如中点数组排序后是[2,3,3,3,4],然后x是1,就从左边开始扫,让x单调递增,到最右边变成5,然后重新计算新的区间中点数组再排序,反过来从右往左,x从n到1再扫一次。每一次扫描只需要消耗2*n的次数,由于每个元素最多被扫10次就被缺点了,所以限制是

4n+20n,远远低于40*n的限制。

这可能是来源于单调递增和单调递减轮流,加速了一半,有点像莫队算法那个思路。

其实如果在寻找1或者寻找x的过程中额外记录了一些信息的话,应该还能再下降这个上限。但是没必要。

posted @ 2024-02-03 06:48  purinliang  阅读(12)  评论(0编辑  收藏  举报