题意简述
有一个刷题机,记录了这样的信息:有一个长度为$n<=1e5$的序列$a$,表示写(>0)或删(<0)了若干行代码。如果删除的代码行数超过了已有的代码行数,那就是保持为$0$行代码。每当你的代码行数$>m$之后,你就会自动AC一个题,代码清空。现在已知你AC了$k$个题。求$m$的范围。无解输出-1.0)了若干行代码。如果删除的代码行数超过了已有的代码行数,那就是保持为$0$行代码。每当你的代码行数$>
思路
很明显,$m$越大$AC$的越少。二分即珂。(话说上海的题怎么这么水)
实现注意
我们怎么判断mid是取$(l+r+1)/2$还是$(l+r)/2$呢?
我刚开始学二分的时候也为这个事情发愁。但是后来我发现一个简单易懂的理解方法。
因为我经常会调试。调试发现,就是$r=l+1$的时候陷入了一个死循环。
我们想想,$r=l+1$的时候,$(l+r)/2$相当于$l$,$(l+r+1)/2$相当于$r$。(换句话说,就是偏左的$mid$和偏右的$mid$)。然后如果我们的条件是$l=mid$,$mid$还取的是$(l+r)/2=l$,那就相当于没有减小,会死循环。所以当条件是$l=mid$,也就是要取最大值的时候,$mid$应该取$(l+r+1)/2$。
同理,当我们要取最小值的时候,也就是$r=mid$的时候,应该$mid=(l+r)/2$,这样才能让区间缩小。
1 |
|