3 条题解

  • 2
    @ 2026-10-8 21:56:54

    题意:给定 n,mn,m 和平面上的 kk 个点,数有多少个矩形(左下 (x1,y1)(x_1,y_1)、右上 (x2,y2)(x_2,y_2),要求 1≤x1≤x2≤n1\le x_1\le x_2\le n、1≤y1≤y2≤m1\le y_1\le y_2\le m)里至少含一个给定点,答案对 109+710^9+7 取模。

    最直白的做法是把所有矩形都枚举一遍。先按输入把点打到一张二维前缀和表上,这样判断「某个矩形里有没有点」就是 O(1)O(1) 的;然后四重循环枚举 x1≤x2x_1\le x_2 与 y1≤y2y_1\le y_2,有就累加。

    代价是 Θ(n2m2)\Theta(n^2m^2),可以过测试点 1,21,2,20 分。

    直接数「至少包含一个给定点的矩形」不好数,改成按 x 方向分列枚举。

    把 kk 个点的 xx 坐标去重排序,得到若干列 v1<v2<⋯<vtv_1<v_2<\dots<v_t(再加两个哨兵 v0=0v_0=0、vt+1=n+1v_{t+1}=n+1)。矩形的左边界 x1x_1 落在哪两条相邻列之间、右边界 x2x_2 落在哪两条之间,一共只有 O(t2)O(t^2) 种「列区间」可以枚举。

    固定一段列区间(矩形至少要横跨第 ii 到第 jj 列里的点)之后再看 y 方向:

    • 左边界 x1x_1 只能在 (vi−1,vi](v_{i-1},v_i] 里取,共 vi−vi−1v_i-v_{i-1} 种;
    • 右边界 x2x_2 只能在 [vj,vj+1)[v_j,v_{j+1}) 里取,共 vj+1−vjv_{j+1}-v_j 种;
    • 中间这些列的点,按 yy 从小到大依次插入有序集合。插入一个点 yy 时设它在已插入集合里的前驱、后继分别是 b,tb,t,那么以这个点为最低点、且 y 区间内至少含一个点的 (y1,y2)(y_1,y_2) 对数正好是 (t−y)(y−b)(t-y)(y-b)。

    把所有点这样累加起来,每一对合法的 (y1,y2)(y_1,y_2) 都会被「它包含的最低那个点」统计恰好一次,不重不漏。于是这段列区间的贡献就是

    $$(\text{y 方向的合法区间数})\times(v_i-v_{i-1})\times(v_{j+1}-v_j)$$

    对所有列区间求和即可。

    列数不超过 k+1k+1,每段列区间的 y 方向扫描用有序集合做,总复杂度 O(k2log⁡k)O(k^2\log k)。

    • @ 2026-10-9 11:56:14

      流程:

      • 固定左右范围之后,从左向右扫描区间内的竖直直线。
      • 在集合中加入哨兵 y=0y = 0 和 y=m+1y=m+1。
      • 对于一条竖直直线,按照 y 从小到大枚举点。
      • 对于当前 y,找出集合中前驱 b、后继 t。以 y 为最下点的矩形上下界组合有 (t−b)(y−b)(t-b)(y-b) 个。将其加入答案。
        • 为什么不是 (m−b+1)(y−b)(m-b+1)(y-b) 呢?这是为了不重复计算。
        • 假设在 t 计算结束之后“以 t 为最低点的所有合法矩形上下边匹配情况” 都已经被计算了。那么所有下底边(0,t](0, t] 匹配 上底边[t,m+1)[t, m+1) 都已经被计算了。
        • 下底边(b,y](b, y] 匹配 上底边[y,t)[y, t) 是没有被算过的。但是,下底边 (b,y](b,y] 匹配 上底边[t,m+1)[t, m+1) 都已经被计算过了。
      • 最后将当前点加入集合。

信息

ID
2782
时间
1000ms
内存
128MiB
难度
7
标签
(无)
递交数
61
已通过
11
上传者