HDU 3207 Highway

题目大意:

不超过10 ^ 5个数, 一开始设定为相同的正整数, 模拟3种操作:

a) 询问一段区间是否连续, 是的话把这一段数减去某个数, 当某个数小于等于0时相当于断开.

b) 把一段区间的数增加一个数, 断开的数不再增加.

c) 把一段区间的数与某个数取max , 断开的数不参与此过程.

 

简要分析:

数据结构题, 分块要好写一些. 假定每个数减到小于0时修改为0. 每一块多维护4个值: 最小值minv, 变化量delta, c操作的标记addto, 还要记录一个offset, 它的含义是指某一块在其他标记存在的情况下, 不超过-offset的块中的数已经断开. 另外注意到b和c两种标记可以这样处理, 在b操作时把c操作的表示也加上那个增加量, 那么当更新一个块时就可以先加上delta再与addto取max. 那么每个操作对一个块标记修改的部分可以这样实现:

a) 设减去的数为d, 则minv = max(0, minv - d), addto = max(0, addto - d), delta -= d, 如果addto为0了再修改offset, offset = min(offset, delta);

b) 设加上的数为d, 则delta += d, 若minv大于0则minv += d, 若addto大于0则addto += d;

c) 设与d取max, 若d大于minv且d大于addto时才有考虑它的必要, addto = d, 若minv大于0则minv=d.

复杂度O(m * sqrt(n)), m为操作次数.

 

代码实现:

View Code

转载于:https://www.cnblogs.com/zcwwzdjn/archive/2012/02/25/2367391.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值