[BZOJ 2658]小蓝的好友

一、题目

在这里插入图片描述

二、解法

正难则反,求至少包含一个黑格子就等于全部减去不包含黑格子的方案数。

考虑单调栈,对于每一行,求出每一个点最长上升,不碰到黑格子的距离,得到一个数组 u p up up,本题的一个重要条件是数据随机,我们对 u p up up数组建立 t r e a p treap treap,其中下标作为减值, u p up up作为修正值,这样建出来的数满足根节点的 u p up up最小,而且由于 u p up up随机,能够保证复杂度是 log ⁡ \log log

考虑每个点的贡献,就是在 t r e a p treap treap中的: ( u p [ x ] − u p [ f a [ x ] ] ) × s i z e [ x ] × ( s i z e [ x ] + 1 ) ÷ 2 (up[x]-up[fa[x]])\times size[x]\times (size[x]+1)\div 2 (up[x]up[fa[x]])×size[x]×(size[x]+1)÷2,求和即可。

怎么理解上式呢?请看下图:
在这里插入图片描述
就比如这样的一颗局部 t r e a p treap treap,我们的根通过上式处理了红色部分的贡献,具体表现为固定 y y y轴下限,在高度差中随意选取 y y y轴上限,左边和右边都在管辖范围( u p up up一定比它大)中乱选(也就是 s i z e size size),体现为等差数列求和,那我们每一个高度都不重不漏的统计,那么一直归纳到最后,就可以发现这种做法的正确性,所以当行的答案我们解决了。

将改行转移到下一行,每一个 u p + 1 up+1 up+1,如果遇到了黑色点那就清零,时间复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn)

没有代码,需要填坑
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值