01 ~ 07/12/2025 做题记录

退役了,平时没事干就做点题吧 233

[NWRRC 2025] Keys and Grates

在数轴上,有 \(n\) 个不同的障碍,每个障碍唯一对应了一把钥匙,散落在不同位置。
你要从 \(S\) 走到 \(T\),求最短路径,或者报告无解。

\(n \le 2 \cdot 10^5\)

手玩一下,观察到我们的路径一定是左右往返。有很多做法,这里学到一个非常巧妙的建图方法:

  • \(S\) 开始向两侧的点连边,左侧向左侧相邻的位置连有向边,右侧向右侧相邻的位置连有向边;
  • 钥匙向门连有向边;

把距离作为边权。我们从 \(S\) 开始,做拓扑排序,有解的充要条件是 \(T\) 可以被入队。
这是因为 \(T\) 想要入队,必须能从一侧抵达;门想要入队,必须同时满足能从一侧抵达,且能从钥匙抵达。
这个连边的方式恰好表示了限制。

同时,在这个这个过程中,求出 \(S\)\(T\)最长路 即为答案。
这是因为前面说了,每个门有两个限制都要满足,其他的则为一个。从定义来看,恰好是最长路。

笔记:存在多个限制要同时满足,则瓶颈是最晚满足的那个限制,故可以得到最长路的建模。

[Ynoi2007] rfplca

给一棵以 \(1\) 为根的树,定义 \(a_i\) 是点 \(i\) 的父亲,满足父亲的编号一定小于自己,有 \(m\) 次操作:

  • 区间减法,但不会小于 \(1\),即 \(\text{max}(a_i - x, 1)\)
  • 查询两个点的 LCA

\(n,m\le 4 \cdot 10^5\)

这个题好像在 \(23\) 还是 \(24\) 年的 \(\text{icpc}\) 里原了(可能是转化完以后),我赛时就没读到这个题,赛后听别人说的,正好退役了,补一下这个题。

考虑如果能满足 \(i - a_i \ge \sqrt n\),那么树高也不超过根号,这个时候暴力查询复杂度就是对的,和树剖的跳法类似。这个限制还能稍微放松一下,我们对编号分块以后,如果 \(a_i\)\(i\) 不在一个块里,那么就认为它已经满足了特殊条件(因为暴力跳的时候,一共只有根号个块可以切换,相当于是找了一个简易的势能)。

现在考虑如果 \(i - a_i\) 很小怎么办,实际上如果写过弹飞绵羊那个题的话,应该马上就会了。我们再设计 \(h_i\) 表示从 \(i\) 出发一直跳,首次跳出自己这个块,抵达的编号。

修改的时候,我们记录每个块被完整地修改了几次,如果减了超过根号次,这个 \(h\) 必然是和 \(a\) 一样的,就不需要单独维护了。否则我们直接重构整个块的每个 \(h\),这样每个块只会重构根号次,于是就做完了。注意如果重构的是散块,那么要一直重构到这个块的尾部(块后半部分的 \(h\) 也会被前半部分的修改影响)。

[BalticOI 2014] Sequence (Day1)

现在有 \(K\) 个连续正整数,每个整数你只能看见其中一位数字,求最开始的数 \(N\) 的最小值。

\(1 \le K \le 10^5\)

个人感觉非常神的一个题,而且有点细节,完全适合当 $\text{xcpc} $ 金牌题。

首先观察答案范围,因为 \(K\) 也不算太大,所以只要 \(1234567890 + 00000\) 就一定能满足任何输入。我们枚举第一个数字的最后一位,这样每个数字的最后一位都确定了。我们考虑次高位,因为是十进制的,所以每 10 个数字才会变一次,相当于是一个 \(k/10\) 的子问题。

经典结论:\(\text{T}(K) = 10\text{T}(K/10) + K = \Theta(K \log K)\),只要子问题数乘分母是 \(1\) 就是对的。

递归的时候可以压位,表示每个位置需要满足出现了哪些数字,然后枚举的时候会满足一些限制,不断递归下去。这个时候会发现,完全变成了数位 \(\text{dp}\) 的写法,细节和难点在于边界怎么处理:

  • 如果递归深度到了 16 那么可以直接返回一个 INF,因为搜到的肯定不是答案,不然会死循环。
  • [重要] 递归到叶子时,表示问题规模不能再分,不代表只有一个数位,叶子可以多填几个数位。
  • 如果叶子的上一层填了 \(0\),那么这一位不能只填 \(0\)
  • 如果叶子只限制了 \(0\),那么填 \(10\)
  • 如果需要满足多个限制,其中有 \(0\),那么最优的是在高位第二个地方填 \(0\)
    举个例子就是填 \(1023456789\),优于 \(1234567890\)

笔记:如果你感觉有点忘了数位 \(\text{dp}\),可以写一次这个题,感觉非常千古。

[CQOI2014] 数三角形

给定一个 \(N\times M\) 的网格,请计算三点都在格点上的三角形共有多少个。注意三角形的三点不能共线。

\(1\le N,M\le1000\)

首先 \(O(NM)\) 的做法很经典,我们求出所有点对数量,然后减去三点共线的数量。枚举每个长边的端点,设横纵坐标的差为 \(x,y\),这里有经典结论:

  • 这条线段不含端点处,遇到的整点数为 \(\gcd(x,y) - 1\)
  • 于是答案就是 \(\sum_{x=1}^n \sum_{y=1}^m (n-x+1)(m-y+1) (\gcd(x,y)-1)\)

我们利用欧拉反演 \(n = \sum_{d|n} \varphi(d)\),得到 \(\gcd(x,y) = \sum_{d|x,d|y} \varphi(d)\)
这里比较巧的是,因子 \(d\) 里必有 \(1\),可以和前面的减一相抵消,可以钦定 \(d\) 要大于 \(1\)

然后去枚举这个 \(d\) 就能得到 \(\sum_{d=2}^{\min(n,m)} \varphi(d) \sum_{i=1}^{n/d} \sum_{j=1}^{m/d} (n-id+1)(m-jd+1)\)
两个求和号单独看是等差数列求和,于是可以 \(O(1)\) 计算每一项,故复杂度变成了 \(O(\min(N,M))\)

笔记:等我再退役几年,以后可以拿这个题热身了,感觉很适合。。。

[IOI 2011] Race

给一棵树,每条边有边权。求一条简单路径,权值和等于 \(k\),且边的数量最小。

\(1 \leq n \leq 2 \times 10^5\)\(0 \leq k,w_i \leq 10^6\)\(0 \leq u_i,v_i \lt n\)

您一眼,点分治秒了。唉我知道学弟都不喜欢写点分治,所以还是要说一下启发式合并,比较好写。

这题比较好的地方是你知道 \(k\) 这个信息,所以我们维护 $ \text{map} _ i $ 表示子树到 \(i\) 的链,权值为 \(x\),边数为 \(v\)
那么合并的时候只需要直接看有没有 \(x = k-L\) 的值,然后把轻儿子的值暴力插入进去即可。

往上走的时候直接对 \(\text{map}\) 全局打 \(\text{tag}\) 表示加了一个边权,并且长度加一。

虽然是 \(O(n \log^2 n)\) 但是常数说得过去,\(\text{xcpc}\) 里一般不是很在意吧。

作诗

给一个正整数序列,强制在线,每次询问一个区间,问区间里多少数字出现了偶数次。

\(n,a,m \le10^5\)

经典分块题,预处理块 \(x\) 到块 \(y\) 的答案,以及在前 \(x\) 个块里颜色 \(c\) 出现了多少次。

每次询问把散块里的颜色拿出来,判断这根号种颜色的贡献。

笔记:单向规约 01 矩阵乘法

posted @ 2025-12-02 14:06  Aurora5090  阅读(19)  评论(0)    收藏  举报

再次右键以切换宽度