• 时代的眼泪


    自己的做法有点奇怪,参考了区间逆序对的做法。
    设一个询问的矩形为((p1,p2),(p3,p4))
    定义(g(i,j))为顶部为(i),右部为(j),左/底部贴着平面的最左/最下边的答案
    由于问题比区间逆序对强,所以考虑分块。
    在分块时,序列被分为了(L,M,R)三个部分,(L,R)是左,右散块,(M)是中间整块。
    每个点的贡献是以它为左下角的矩形和询问矩形的交。
    (L,R)的贡献可以枚举(L)的每个节点,这样子贡献就是(R)平面上的一个子平面。
    把每个块内的(a)离散化后显然可以二维前缀和。
    为了避免二分,每个块(i)需要维护(f_{i,j})表示第(i)个块内小于(j)的最大数的排名。
    (L,M)(M,R)的贡献是对称的,所以只需要处理(L,M)的贡献。
    二维前缀和后,转化成了计算顶部任意,右部贴着某个块,左/底部贴着平面的最左/最下边的答案。
    (s_{i,j})表示右部为第(i)个块的右端点,顶部为(j)的答案,显然可以把前(i)个块内的点排序后求。
    (M)内部的每个节点的贡献可以被拆成在块内,块外的。
    块内的贡献事实上就是求块内的纵坐标在查询下界,上界的点的逆序对个数。
    一个块内最多只有(sqrt{n}*sqrt{n}=n)类贡献,可以通过前面的二维前缀和,枚举左端点,右端点递增处理。
    找下界,上界在这个块内对应的贡献类型可以用前面提到的(f)
    设当前最右的整块的右部横坐标为(p)
    设当前考虑的节点为(i)(i)所在块的右部横坐标为(q),扫描(M)的整块做处理。则我们要求矩形([(q,a_i+1),(p,p4)])内的点数。
    二维差分后变成(g(p,p4)-g(p,a_i)-g(q,p4)+g(q,a_i))
    (g(p,p4))(g(q,p4))贡献和(i)无关,显然可以用前面提到的二维前缀和求出(i)的个数。
    由于(p4)贴在块的右端点上,所以可以用前面提到的(s)求。
    (g(i,a_i))可以在块内维护一个前缀和(t)(t_i)表示(g(i,a_i)),找标号可以用以前的数组(f)
    (g(q,a_i))可以把这个块挂在(q)的块上。
    这事实上是一些点有权值,要求一个左部贴着某个块的左部,右部贴着某个块的右部平面的点的权值和。
    由于矩形贴在块的右端点上,所以可以用前面提到的(s)求。
    可以给每个块再维护一个前缀和,然后扫描每个当前询问包含的块,用(f)内的数组求出标号后用前缀和求出答案。
    时间复杂度(O((n+m)sqrt{n})),感觉常数很大。

  • 相关阅读:
    第72天: PySpider框架的使用
    第71天: Python Scrapy 项目实战
    Web前端资源汇总
    1201即将到来
    C#自定义事件模拟风吹草摇摆
    HTML5 Canvas爱心时钟代码
    CSS3圆环动态弹出菜单
    CSS3实现Loading动画特效
    HTML5优势
    CSS3扁平化Loading动画特效
  • 原文地址:https://www.cnblogs.com/ctmlpfs/p/14999327.html
Copyright © 2020-2023  润新知