日记

日记

Mon Jul 14 2025
4 分钟

码力得到史诗级增强。

Link to 堆

给定有 nn 个数的数组 aa。有 qq 次询问,每次询问给定一个 pp,要求进行 nn 次操作。初始有可重集 S={aii[1,p]}S = \{a_i \mid i \in [1,p]\}。第 ii 次操作的流程如下:

  1. 取出 SS 里最大的数 xx,让 sumsum 加上 (1)i1x(-1)^{i - 1} \cdot x,将 xxSS 里删除。
  2. 如果 p+inp + i \le n,将 ap+ia_{p + i} 加入 ss

求每次询问过后请输出 sumsum 的值。

我们先进行 11 次 1 操作,那样操作顺序就反过来了。然后我们经过一番手模,发现这时 xx 是单调不增的,因为要是有 ap+i>xa_{p + i} > x 就直接被取走了。我们可以每次操作用 cntcnt 数组记录每个数的出现次数。维护一个 maxmax 指针,初始为 nn。每次询问就直接去模拟:

  • 加入的 ap+i<maxa_{p + i} < max
    取出 maxmax 然后往下暴力找新的 maxmax
  • 加入的 ap+imaxa_{p + i} \ge max
    直接取 ap+ia_{p + i}maxmax 不变。

然后直接输出模拟出来的 sumsum,每次询问复杂度 O(n)O(n),总复杂度 O(nq)O(nq)。需要 现代硬件上的常数优化

不让宋佳兴来讲卡常简直可惜了。

列队 Link to

我们发现行之间都是独立的,所以我们可以把整个矩阵分成这个样子:

然后我们发现我们需要一个这样的数据结构:支持插入一个数,删除一个数。我们一看:平衡树!!但是太难写了,于是我们决定使用权值树状数组。先把所有的数都置为 11。每次删除的时候二分出来第 kk11,将其置为 00 就是了。然后有加入进来的外来数就用 vector 存下来就是了。

小明的树 Link to

我居然能在不看 std 的情况下自己打出来一个实现还算优秀的 AC 代码?

设第 ii 个点在 aia_i 时刻被点亮。

考虑如果是记美丽的时刻的个数如何做。我们发现一个时刻美丽当且仅当所有未点亮的灯泡形成一个连通块。而如何记连通块个数呢?设第 ii 个时刻时,连通块个数有 XiX_i 个。我们发现连通块个数等于点数减边数。而在时刻 iinin - i 个未点亮的点。那么 Xi=ni两端都没点亮的边数X_i = n - i - \text{两端都没点亮的边数}。我们发现对于边 (u,v)(u,v),它会对 i[1,min(au,av))i \in [1,\min(a_u,a_v))XiX_i 做出 1-1 的贡献。那么答案就是最小值的个数,可以用线段树维护。

但是我们的答案并不是记“美丽时刻的个数”。我们设 YiY_i 表示第 ii 时刻亮灯的灯泡的连通块个数。效仿 XXYi=i两边都亮灯的边个数Y_i = i - \text{两边都亮灯的边个数}。那么显然,边 (u,v)(u,v) 会对 i[max(au,av),n)i \in [\max(a_u,a_v),n)YiY_i 造成贡献。

我们用线段树维护:XiX_i 的最小值;XiX_i 最小值的个数;XiX_i 是最小值的位置的 YiY_i 的和。那么边的变化就是对 X,YX,Y 的区间加减。直接维护就行了。

后日谈 Link to 后日谈

其实黑题也没那么难哈。