zyb讲题笔记1

1. P2208 [USACO13OPEN] What’s Up With Gravity S

解法

分层图,共两层,第一层是重力正方向,第二层是重力反方向。当一个点在当前重力下,下方为实心方块,可以左右走或反转重力;下方为空心则只能向下掉。在同一重力下(即一层内)边权为 0 0 0, 反转重力(跨越图层的边)边权为 1 1 1。可以 01bfs,复杂度 O ( n 2 ) \mathcal{O}(n^2) O(n2)

提交记录

2. P3527 [POI2011] MET-Meteors

解法 1

主席树,第 i i i 棵树的 [ l , r ] [l,r] [l,r] 表示时间在 i i i 时空间站 [ l , r ] [l,r] [l,r] 的陨石样本总数。然后对每个国家二分。时间( n , m , k n,m,k n,m,k 同阶) O ( n log ⁡ 2 n ) \mathcal{O}(n\log^2n) O(nlog2n)

提交记录

解法 2

整体二分,二分时间 [ l , r ] [l,r] [l,r],过程中对国家进行分类即可。

提交记录

3. P6815 [PA2009] Cakes

首先暴力,枚举所有点 u u u,再枚举与之相连的所有 v v v 并记录,然后枚举与 v v v 相连的 w w w,若记录下 w w w u u u 相连,则统计答案。记枚举 u , v , w u,v,w u,v,w 分别为第 1 , 2 , 3 1,2,3 1,2,3 层。考虑到第 1 , 2 1,2 1,2 层相当于枚举边,所以复杂度 O ( n m ) \mathcal{O}(nm) O(nm)。然而第 2 , 3 2,3 2,3 层复杂度相同,则复杂度又为 O ( ∑ i − 1 n d e g i 2 ) \mathcal{O}(\sum_{i-1}^n deg_i^2) O(i1ndegi2) d e g deg deg 表示度数)。同时又注意到每条边实际正反枚举了两次,所以考虑在使每条边只被枚举一个方向时,尽可能不要有太大的 d e g i deg_i degi,这样平方后可以降低复杂度。所以自然想到对于每条边的两个端点选取一个关键点,或者认为将边改为有向,从关键点到非关键点,即在关键点枚举时才能枚举到该边。贪心地想到:当 d e g u < d e g v deg_u<deg_v degu<degv 时,连边 u → v u\to v uv

但是更多问题来了:这样做能否使每个三元环恰好遍历一次吗?这样做的复杂度又能是多少?

对于第一个问题,容易想到统计在 u u u 进行时,存在边 u → v , u → w u\to v,u\to w uv,uw,即有两个出度,进而可知定向后三元环不能有环就足以保证。那么能否有环呢?按照度数大小,这样是不会错的,但是问题指向一种特别情况 d e g u = d e g v = d e g w deg_u=deg_v=deg_w degu=degv=degw,发现之前的贪心策略不能在此模棱两可,这时我们只要用一个对每个点有严格大小关系的属性区分就好了,自然想到序号,故当 d e g u = d e g v deg_u=deg_v degu=degv 并且 u < v u<v u<v (反过来也可)时,连边 u → v u\to v uv

对于第二个问题,对于一个点 u u u,若度数比他大的有 x x x 个,则最多连出 min ⁡ { d e g u , x } \min\left\{deg_u,x\right\} min{degu,x} 条边,而 x ⋅ d e g u ≤ m x\cdot deg_u\le m xdegum,则一个点连出的边 ≤ m \le\sqrt m m 。所以总复杂度 O ( m m ) \mathcal{O}(m\sqrt m) O(mm )

最后,此题需要卡常,这里给出一个反常的操作,用 vector 邻接表存而不用链式前向星存。因为 vector 中内存连续,对于密集图更为高效。

提交记录

4. #191. 无向图四元环计数

沿用上一题的思路,将无向边有向化。

考虑一个四元环的特征:由两个首尾节点相同中间节点不同节点个数为三的链合成。也可抽象为两个点以及与它们共同相连的两个点。

复习上一节内容:我们可以通过结合度数和具有严格大小关系的量(如序号)来区分边的方向,记最终表明这种关系大小为权值的大小。

难点在于:我们如何唯一枚举这样的三元链结构,然后组合计数求解。发现我们可以先定一个首(尾)节点,记为 u u u,同时使它是四元环的最大权值点。那么我们可以从 u u u 枚举 v v v,在从 v v v 枚举 w w w。要使 v , w v,w v,w 的权值都小于 u u u 的。那么可以唯一确定这种三元链,然后在 w w w 上统计这种三元链的数量 k k k,四元环数即为 k ( k − 1 ) 2 \frac{k(k-1)}{2} 2k(k1)。这样第一层枚举是 u u u v v v 权值从大到小的有向边,而第二层枚举是 v v v w w w 的无向边,接下来会结合错误理解来解释为何复杂度为 O ( m m ) \mathcal{O}(m\sqrt m) O(mm )。(你问为什么这次似乎从权值大往小算?下面也会说)

【错误理解】我们先给每个点一个权值,然后是要按这个权值来连边和求解,这里就出现了两种思路:
1.将权值小的点向权值大的点连边,统计时让最外层的点在四元环权值里最小
2.将权值大的点向权值小的点连边,统计时让最外层的点在四元环权值里最大
lz采取了第一种思路,T飞了。oi-wiki采取了第二种做法,过掉了。
所以这两者到底有什么区别?

解释:复杂度本质上是不同的,第一个是 O ( m 2 ) \mathcal{O}(m^2) O(m2),第二个是 O ( m m ) \mathcal{O}(m\sqrt m) O(mm )。感性地理解是前者 v v v 度数更大,枚举 w w w 更慢。稍微严格地讲,第二种从 v v v u u u (反过来看)的边是从小到大的,故枚举 u u u v v v O ( n m ) \mathcal{O}(n\sqrt m) O(nm )(这个 n n n 可以理解为枚举 v v v),然后套上第三层枚举 w w w 就是把 n n n v v v 变成 2 m 2m 2m 条边。而前者不能这样推理,比如我让 v v v 的边数特别多就会卡掉。但是前者也是可以修改的,比较简单的想法是枚举 u , v u,v u,v 是在无向图上,共 2 m 2m 2m,然后再按度数枚举 v , w v,w v,w 就又是 m \sqrt m m ,相当于将第一种反过来。

总复杂度 O ( m m ) \mathcal{O}(m\sqrt m) O(mm )。感觉是很难的思维题。

code

5. 二进制骇客

显然 dp,然后瞬间就好了。

f ( i , j ) f(i,j) f(i,j) 表示打字第 i i i 个操作,匹配字符前 j j j 个的方案数。

f ( i , j ) ← f ( i − 1 , j − 1 ) + 2 f ( i − 1 , j + 1 ) f(i,j)\gets f(i-1,j-1)+2f(i-1,j+1) f(i,j)f(i1,j1)+2f(i1,j+1)

解释就是可以打一个正确的,或删除一个(注意这个不一定要正确,而具体哪个正确无关紧要,所以可以直接 2 × 2\times 2×,涵盖不正确的打法)。注意 j = 0 j=0 j=0 特判。

复杂度 O ( n 2 ) \mathcal{O}(n^2) O(n2)

太简单了,代码自己去写吧。(实在要私我,不想弄个链接了)

6. P1081 [NOIP2012 提高组] 开车旅行

模拟我的思考过程(虽然中间看了一眼标签)。读一遍题,意思很抽象,但有个很特别的切入口:比值最小,这个一般两种处理方法:二分答案(01分数规划),和枚举。然后我发现枚举起点就行了,因为给定起点和最大路程,一定能求出比值。这其实与第二问很相似。首先想到暴力模拟,处理每一天开车情况,发现旅行途中路程单调增(显然),再加上看到的标签(倍增)(但是你不看多想想或许也能想到),所以预处理倍增,预期复杂度 O ( n log ⁡ n ) \mathcal{O}(n\log n) O(nlogn)

参考用倍增优化 lca 的方法。接下来的事都很显然了,你需要维护如下三元组的数据: ( i , j , k ) (i,j,k) (i,j,k) 表示从 i i i 出发,旅行 2 j 2^j 2j 天,开始时是 k k k 开车,会到达哪里?A 行驶多远?B 行驶多远?然后求答案:从大往小枚举 j j j,对于定长 x x x,如果能走就走,不能走就继续枚举。

动动脑就能想出来怎么写的,而且我感觉洛谷难度虚高。

code

7. [SDOI2010] 粟粟的书架

根据数据范围,我们发现要分类讨论。

后 50% 的可视为一维的,发现正好是主席树。具体做法也很简单,第 i i i 个根上的主席树维护整个数列中,前 i i i 大的数在 [ l , r ] [l,r] [l,r] 上有多少个以及和为多少。查询可以二分再主席树询问。注意相同值的先后不会影响最终结果。复杂度 O ( M log ⁡ 2 n ) \mathcal{O}(M\log^2n) O(Mlog2n)

前 50% 的数据,其实二分的思想仍然是需要的。由于最多也只有 4 × 1 0 4 4\times10^4 4×104 个数字,所以对所有位置可以维护一个二维前缀和,这样可以快速差分得到矩形区间数据。同时发现 P i , j ≤ 1000 P_{i,j}\le1000 Pi,j1000,所以维护 s ( i , j , k ) s(i,j,k) s(i,j,k) 表示 1 ∼ i 1\sim i 1i 1 ∼ j 1\sim j 1j 矩形区间中值 ≥ 1000 \ge1000 1000 的点个数及其总和,可以递推算出。查询也是二分即可。但是这里需要处理相同值。方法也很简单,最终得到的答案以及 k k k(按照上述定义,即所选数 ≥ k \ge k k),看看减去若干 k k k 是否任满足条件即可。复杂度 O ( M log ⁡ n + n 2 P m a x ) \mathcal{O}(M\log n+n^2P_{max}) O(Mlogn+n2Pmax)

code

8.罗马游戏

理清思路:我们需要知道:一个人的团队情况、死活,以及团队最小分数者。典型的启发式合并。这里不讲线段树合并做法,因为直接使用 std::set 即可满足需求,且原理是相通的。

团队情况可以并查集维护,死活直接记录。对于每个团队,需要维护一个 std::set,就可以知道最小分数者了。合并方法就是启发式合并(具体来说就是小的合到大的里),可以证明其复杂度为 O ( n log ⁡ n ) \mathcal{O}(n\log n) O(nlogn)

code

9 ~ 12 CODE

9. 对比

非常易错的思维题。我一开始的直觉是如果有一个数字出现次数大于一半,则不可能。然而事与愿违。

后来又是凭感觉,将 B B B 平移一下就可以了。其实画个折线图什么的也可以看出来,那么问题是平移多长距离。我的想法是对于一个数字使其满足不重叠,算出向右平移的长度 K ( 0 ≤ K ≤ n − 1 ) K(0\le K\le n-1) K(0Kn1) 的取值范围,显然这是个区间,然后所有区间取交。

10. 大魔术师

背包,但不能硬上。考虑同余。

枚举选物品数 K K K,那么选的 ∑ a i \sum{a_i} ai 应当与 X X X 同余。然后就可以背包了: f ( j , u , v ) f(j,u,v) f(j,u,v) 表示决策第 j j j 个物品,已选 u u u 个物品,当前所选的 ∑ a i ≡ v    ( m o d    K ) \sum{a_i}\equiv v\;(mod\;K) aiv(modK)。具体不明白看代码吧。

11. 插入操作

组合计数问题,又是思维题。我的想法是将问题转化一下:在长度为 ∣ S ∣ + K |S|+K S+K 的所有可能字符串中,有多少包含不连续子串 S S S。那么我们只要知道一个字符串是否包含不连续子串 S S S 即可,所以我们不妨使组成 S S S 的所有字符都在尽可能靠前的位置,如(粗体为 S S S):foooffof。然后我们要满足的构造条件是两个 S S S 的字符之间没有后一个。进而我们容易得到 dp 方程 f ( i , j ) = f ( i − 1 , j − 1 ) + 25 f ( i − 1 , j ) f(i,j)=f(i-1,j-1)+25f(i-1,j) f(i,j)=f(i1,j1)+25f(i1,j) (表示长度为 ∣ S ∣ + K |S|+K S+K 的所有可能字符串的第 i i i 位, S S S 的第 j j j 位)。

关于如何统计答案: ∑ f ( i , ∣ S ∣ − 1 ) × 2 6 ∣ S ∣ + K − i − 1 \sum f(i,|S|-1)\times26^{|S|+K-i-1} f(i,S1)×26S+Ki1。继续考虑优化,(作图或者根据逻辑推到)发现 f ( i , ∣ S ∣ − 1 ) = ( i ∣ S ∣ − 1 ) × 2 5 i − ∣ S ∣ + 1 f(i,|S|-1)={i\choose |S|-1}\times25^{i-|S|+1} f(i,S1)=(S1i)×25iS+1。然后就结束了。

12. 树上距离

无聊的题,你或许可以试试树剖,但我觉得会被卡常。所以我想弄个更简练的做法:我们肯定要先弄个 lca,然后边权前缀和。考虑修改一个边权,会影响一个子树。根据 dfs 序建立数组,在一个子树中的点的编号是连续的,然后可以转线性,然后可以快速修改查询,然后完事了。

13. [ABC283E] Don‘t Isolate Elements

发现每一行的独立性只与上下两行有关,考虑 dp。设 f ( i , 1 / 0 , 1 / 0 ) f(i,1/0,1/0) f(i,1/0,1/0) 表示已决策前 i i i 行,第 i i i 行是否反转,第 i − 1 i-1 i1 行是否反转。然后关于转移:决策第 i i i 行,若 A i − 1 , j A_{i-1,j} Ai1,j 在前 i − 1 i-1 i1 行孤立(不考虑下面的第 i i i 行),那么 A i , j A_{i,j} Ai,j 必须为 A i − 1 , j A_{i-1,j} Ai1,j 的反。换句话说,对于 A i − 1 , j A_{i-1,j} Ai1,j 为第 i − 1 i-1 i1 行的孤立元素(只看左右),若不存在 A i , j ≠ A i − 1 , j A_{i,j}\neq A_{i-1,j} Ai,j=Ai1,j A i − 2 , j ≠ A i − 1 , j A_{i-2,j}\neq A_{i-1,j} Ai2,j=Ai1,j,则可行。以此类推至所有关于第 i i i 行与第 i − 1 i-1 i1 行是否反转状态。我们可以使 f ( i , 1 / 0 , 1 / 0 ) f(i,1/0,1/0) f(i,1/0,1/0) 表示最多反转数,最后被 n n n 减即为最少反转数。

code

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值