[BZOJ 2658]小蓝的好友

一、题目

在这里插入图片描述

二、解法

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

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

考虑每个点的贡献,就是在 t r e a p 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 ,求和即可。

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

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

没有代码,需要填坑
发布了217 篇原创文章 · 获赞 12 · 访问量 5156

猜你喜欢

转载自blog.csdn.net/C202044zxy/article/details/104055681