(CSP2019模拟)结界[生与死的境界]

题意

给定一个长度为 n n n的序列 a a a,有 q q q次询问,每次询问一个区间 [ l , r ] [l,r] [l,r],对区间内的数可进行若干次操作,每次合并相邻的两个数 x , y x,y x,y,变为 x + 2 y x+2y x+2y,最后变为 1 1 1个数,求最终数的最大值。询问无后效性。
数据范围: 1 ≤ n , q ≤ 1 0 5 , − 1 0 9 ≤ a i ≤ 1 0 9 1\le n,q \le 10^{5},- 10^{9} \le a_i \le 10^{9} 1n,q105,109ai109
部分分: 0 ≤ a i ( 10 p t s ) , n , q ≤ 5000 ( 50 p t s ) 0\le a_i (10pts),n,q\le5000(50pts) 0ai(10pts)n,q5000(50pts)

题解

先考虑 0 ≤ a i 0\le a_i 0ai的情况,发现一个数的贡献为2的它与左边的数合并次数次方,于是尽量让数往左边合并,而一个数最多能向左合并的次数为它左边的数的个数,从最后一个往前依次合并恰好能做到。
考虑遇到一个负的ai,第一次遇到的时候还是照常合并,因为这个ai至少要贡献1,这样合并不会使它更劣,且能兼顾后面的最优。那么什么时候不行呢?若当前后面的总贡献已经<0了,那肯定不能再往左合并,而是要从下一个新开一段,这样一直贪心取完效率 O ( n × q ) O(n \times q) O(n×q)
由于是多组询问,若从后往前考虑,则对于不同的终点,每次新加一个数,其贡献要考虑后面那一段,是不独立的,且划分段的方案也不同,故不好计算。考虑从前往后做,每个数的贡献即为它在所在段的位置,而对于不同起点,其划分段的方案是相同的【即一个数若为正就与前一段合并(这可能导致该段若变正数,会再与之前的段合并),否则自己一段】,这样就可以从前往后扫一遍,维护每一个点所属的段及前缀和,每次对右端点在当前位置的询问查询即可。
注意到负数判断是不能取模的,要进行一些特判(细节调到自闭)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值