讲氪总结

· · 个人记录

20240404 讲题总结

Trick

Cheese Point

20240405 讲题总结

20240406 讲题总结 & 解

附: 算术 的解

20240411 讲题总结

20240412 讲题总结

20240503 讲上午题总结 & 哈哈一大半都是原

20240503 讲下午题总结 & 哈哈一大半都不会

附: 讲上午课 & 下午课内容

20240504 讲题总结

附: 讲课内容

20240505 好题分享

20240506 好题分享

20240507 好题分享

附: 讲课内容

20240521-0621 PTY 特供题单 (精简版)

20240623-0714 PTY 特供题单 (精简版)

20240715-0902 PTY 特供题单 (精简版)

20240903 梦熊题单

20240910 wxl 好题分享

20240912 梦熊题单

20240918 qyb 好题分享

20240912 梦熊题单

20240924 hjc 好题分享

20240929 梦熊题单

20241001 syc 好题分享

20241008 梦熊题单

水题单, 只有 c 还有点意思.

20241015 梦熊题单

20241022 xh 好题分享

20241028 dyf 好题分享

20241029 梦熊题单

20241105 lsl 好题分享

20241106 梦熊题单

20241106 梦熊题单

byd 在做完这两道题后这天考的两个 Trick 怎么一个想了 1h 一个直接不会.

20241112 fzx 好题分享

20241113 梦熊题单

i 不会啊

20241119 jjz 好题分享

20241122 梦熊题单

k 不会啊

20241127 梦熊题单

d 我想假了啊

g i 很好啊 我是容斥废物

h 是大奋题啊

j 很复杂不想写啊

20241216 代码源 1

https://www.luogu.com.cn/api/team/downloadFile/82i7o190

20241218 代码源 2

https://qoj.ac/contest/1872

20241220 代码源 3

CF2052K CF2052H CF2052C CF1930H CF1801E QOJ8922 QOJ9798 QOJ9800 QOJ9809

20241223 代码源 4

P11343~11348

20241225 代码源 5

P11105-11107 P11109-11111

20241230 代码源 6

QOJ1257 ajo2024final A~E

20250103 代码源 7

AGC070 A-D CF2053G-I2

20250106 代码源 8

题 & 解

比较套路的题: https://vjudge.net/problem/TopCoder-14588 dfs序计数。

dp[S][u] 表示 u 为根,S 这个点集的 dfs 序。删去 S 之后分成若干个联通块,可以任意排列。

DAG容斥:

dp[S] 表示 S 这个点集定向之后是 DAG 的方案。考虑枚举源点的的一个子集,系数为 (-1)^ (点数-1)。

acyclic orientation 等于 色多项式 P(x) (-1)^n P(-1)。应用:网格图 acyclic orientation

https://codeforces.com/gym/102012/problem/L 可以至少做到 O(bell(m) poly(nm))

https://atcoder.jp/contests/abc306/tasks/abc306_h DAG容斥

定向,使得相等或者 DAG。类似枚举子集。

https://uoj.ac/problem/37 强联通图计数,DAG容斥。

枚举点改成枚举 SCC 的子集即可。

https://qoj.ac/contest/1543/problem/8325 DAG容斥

先求出每个块的拓扑序。然后要求整体直接有拓扑序,类似前面的,枚举子集。

直接做可能是 O(3^n * n^2) 的,其中一维可以用插值优化。

https://acm.hdu.edu.cn/showproblem.php?pid=5330 简单的魔改高维前缀和

dp[i][s1][s2][k] 表示和前 i 位为 s1 的所有串,后 s2 位的距离为 k 的方案数。

https://atcoder.jp/contests/agc017/tasks/agc017_f 魔改高维前缀和。

回顾前缀和,按某种顺序确定,这一位删或者不删。这样能保证每个点向子集恰好一条路径即可。

这里可以考虑路径上每一格要不要翻转,这样可以做到 O(2^n * n)。或者也可以按题解说的从上往下决定每一位要不要翻。

https://atcoder.jp/contests/agc024/tasks/agc024_f 魔改高维前缀和。

状态设计成已经确定了 t 的前几位,s现在后面还有几位的方案。等比数列算一下应该是 O(2^n * n)

https://qoj.ac/problem/2068 2^(n/2) 求一般图匹配的手法

把 2i-1 和 2i 连一条边,整个图会变成若干个环和链。可以用 2^(n/2) * n^2 算出来。后面子集并,

https://codeforces.com/contest/468/problem/E 2^pathwidth 的状压 dp 手法

构造一个顺序状压,每次只需要统计压一下有边跨过这个位置的点的状态即可。这个最大的值叫做pathwidth。

有如下的理论结果,可以理解成非常小常数的 2^O(n):

In any cubic graph, or more generally any graph with maximum vertex degree three, the pathwidth is at most n⁄6 + o(n), where n is the number of vertices in the graph. There exist cubic graphs with pathwidth 0.082n, but it is not known how to reduce this gap between this lower bound and the n⁄6 upper bound.

咋克的近似做法:对于每一列,枚举额外增加的是哪一行,或是不选择额外增加的,然后状压哪些行已经被占用了。考虑优化。注意到如果一行在之后的列都不会用到了,那就可以不状压这行。注意到如果一行的元素很少,那我们去掉这一行就会很容易。于是每次找到元素数最少的行,并找到用到这行的列,先枚举这些被用到的列。这样跑得飞快,在 CF 上是最优解(截至 2021.11.4)。

https://loj.ac/p/6719

题解写了集合幂级数的 exp,ln。众所周知在 n<=18 的情况下,2^n * n^2 和 3^(n-1) 跑的差不多快,所以只要暴力就行了。

考虑这么个过程,初始都是一些环和单点。然后考虑从 1 到 n,每个点把边上的块并起来。

几个比较杂的题,不一定讲。

https://codeforces.com/gym/102759/problem/C 定向,最小代价强联通图。处理手法比较神秘。

每次从当前的 SCC 上面伸一条回自己的路径。然后对着这个过程压即可。

https://atcoder.jp/contests/agc016/tasks/agc016_f 删源点。

每次删去 sg = 0 的点之后,我们发现每个点的 sg 值恰好减一。(这个思路和求树 hackenbush 有点类似)

https://qoj.ac/contest/1648/problem/8364 更加有手法的高维前缀和。

https://acm.hdu.edu.cn/showproblem.php?pid=7470 十分魔怔的压状态方法。 https://acm.hdu.edu.cn/showproblem.php?pid=7476 https://uoj.ac/contest/43/problem/372 https://codeforces.com/contest/1569/problem/F 杂题,想办法压状态 https://loj.ac/p/6729 边双联通计数。和仙人掌有点类似。

https://vjudge.net/problem/TopCoder-14299 直接偷 2^pathwidth 的做法即可。

总结

20250108 代码源 9

https://qoj.ac/contest/1890 CDEFL https://codeforces.com/contest/2057 FG

20250110 代码源 10

https://qoj.ac/category/341

20250206 代码源 11

https://codeforces.com/problemset/problem/1423/M CF833B https://www.luogu.com.cn/problem/P3515 QOJ9540

LOJ6039 QOJ9737 https://codeforces.com/gym/102586/problem/B https://qoj.ac/contest/796/problem/2211 https://atcoder.jp/contests/abc383/tasks/abc383_g

https://codeforces.com/gym/103102/problem/A https://codeforces.com/problemset/problem/1787/H https://codeforces.com/contest/1534/problem/G https://qoj.ac/contest/1648/problem/8362 https://codeforces.com/gym/104128/problem/H

20250217 代码源 12

题 & 解

CF 2046D

感觉非常像 flow,用流表示每个人的行动。每个点的入边至少是 1,然后出边是 ai,加上原来进来的那个人。从原点连过来的边第一个流量需要费用,后面不需要,求一个最小费用可行流。

编一下具体的细节:

  1. 一个 SCC 会产生环流。所以需要提前把 SCC 缩一下。
  2. 一个 SCC 里面可能没有人,不能从原点连边。
  3. 最小费用流,拆流量不会优先走需要代价的边。解决方法建立新点,流量流向入需要需要费用,流向出不需要费用。或者也可以入向出连一条流量为 1,费用为 -1 的边,表示如果入边非零那么就能 -1。

CF 2029I

最小方差,容易想到枚举方差是多少。

接下来你要增广 m 次,求一下最短的增广路径即可。这部分可以暴力 O(n)。总的时间复杂度 O((nm)^2)。

CF 2041G

想法感觉比较直接,难点是找到一个,能写出来的做法。

直接离散化,缩图好像并不太简单,比如一个长条可能需要区分两端的点之类的。

一个参考的做法是首先把边框上全是黑格的行/列去掉,对整个外边界建一个点。然后两条线在不同列对角相邻就连边。这样白格不连通当且仅当黑格成环。然后比较好判了。

CF 2041 K

最大反链不超过 16,表示整个图可以划分成不超过 16 条链。

对于每条链,可以通过 BFS 计算可达。难点在于如何划分,如果直接跑网络流相关的,需要的是 n - 16 次增广而不是 16 次。

事实上如果贪心的每次找到一条最长链去掉,那么会被划分成不超过 O(k log n) 条链。因为最大反链不超过 k,所以图里面的最长链一定超过 n/k,也就是最后的链不超过 log n / log (k/(k-1))。

似乎有一些乱搞或者是对的做法:比如随机选一个点,求出 in 和 out,如果 in 的大小小于 out,那么在 in 里面的点肯定不会是答案,可以全都删除。

类似的题目:https://qoj.ac/problem/8943

CF 1815 F

比较困难的题。想法就是类似求染色,我们按某个顺序逐位确定这些点,我们要保证每个点不会和前面的矛盾。后面的不管。

可以通过枚举发现,三角形在固定前面两个数字之后,第三个数字仍然有机会取到比较多的值。并且第二个数也可以有多种取法。

然后注意到 |A+B| >= |A| + |B| - 1,每个点如果是第二个点,它会贡献一个邻居,并且一个多余的取值。如果是第三个点,它会贡献两个邻居,两个多余的取值,所以我们这个点一定有得选。

CF 1835 F

首先这个就是 Hall 定理。Hall 定理的反例,只要增广爆了就能找到。

然后假设找到了一组完备匹配,刻画一下好的集合。因为存在一个完备匹配,那么好的集合也就是 S = {u1, u2, ..., uk} 然后 N(S) = {p[u1], p[u2], ..., p[uk]}。也就是一个点被选入之后,它在残量网络上可达的点也要被选入。

如果残量网络的可达性不变,那么这个好的关系也不会变。

对于一个 SCC,使用环可以构造。对于缩完之后的 DAG,找最小边使得可达关系不变,是个经典的贪心问题。

arc176_e

数据范围比较的诈骗,实际上不太存在 O(2^n) 或者 O(n!) 枚举然后贪心之类的做法。

用切糕的方法建模,把 X Y 都拆一条链。每个操作建一个点,看这个点在 S 或者 T 中表示给 X 或者 Y 取 max,求最小割即可。

arc153_f

显然大多数情况下,乱染色,是会出现三种颜色的路径的。刻画一下三种颜色都有,并且所有简单路径都不是三色的情况。

首先对于树的情况,容易发现一定有一个点边上有三种颜色。这个统计比较简单。

如果一个环染了多种颜色,能发现其实很难做到合法。可以通过手玩和猜结论得到差不多的结果。这边还是学一下题解的讨论方式。

如果有一个三色的简单环:

如果有一个双色的简单环,但没有三色环,通过一些讨论可以得到不合法。

每个环同色,那么就缩一下点双,变成树的情况。

arc164_f

首先注意到每个点被翻转次数是固定的,也就是取了之后获得分数只和层数有关。

首先可以想到会抢 +1 的叶子,然后只剩一些 -1 的叶子。为了方便起见,我们称 -1 为坏点,1 为好点。目标选到尽量少的坏点。

现在只剩下一些坏叶子,如果是最后一个坏叶子,那么对手能选它的父亲,非常亏,并且不能交换先后手,也就是你要继续选坏点。所以你可以把它看成若干个单独的坏点,以及一个坏点和好点分成一组。

继续往上思考,对于一个坏点,有若干个好儿子,根据前面的分析,可以认为好儿子只有一个坏的儿子,并且是叶子。只有当没有可以选的时候才会去选这个分支,并且如果不把所有分支选完一定不会改变先后手。所以肯定会把所有的分支一起选完。

继续往上,对于一个好点,如果有若干个坏儿子,我们会按从小到大的顺序贪心地选这些坏儿子,把最大的分支放到最后取考虑。

也就是按奇偶分层跑 dp,坏点会把儿子的 dp 值都加起来。好点只保留最大的,把较小的单独当成一组。最后两个人会按照坏点个数从小到大选取这些组。

QOJ 9276

首先如果一列只有一个数字,那么这个数字是固定的。可以把固定的数字做一个类似拓扑排序固定下来。如果已经有白卡的列,也不需要继续考虑。

现在每列至少有两个元素。根据题目描述,存在一个方案,使得至多一个白卡。如果找到这个方案,然后再全部取翻就能得到一组合法解。但是找到这个方案是 NP Complete 的。

但是因为解的存在性,所以每列任意保留两个还是有解的!然后就可以 2-SAT 了。

QOJ 1197

非常困难的题。首先可以想到这是个网络流题。

首先可以先画黑条,再画白条,再画单点。并且一个点,同向只会被画一次。实际上主要确定每个点横向是不是被黑/白条画过,竖向是不是被黑白条画过,分别记作bh, wh, bv, wv。可以唯一确定整个的代价。由于问题比较复杂,所以用更加代数化的方法解决。即最小割可以被刻画成 a x(u) + b !x(u) + c x(u) !x(v)。

具体的,对于画条本身的代价为 a bh(i, j) + b bh(i, j) * !bh(i, j + 1),四个方向都同理。这里保证单点不优,所以不需要考虑长度大于等于 2 的限制。

因为保证了最优解里面同向的只会被涂一次,所以不需要考虑画条导致某个位置被画了多次的情况。

对于单点涂黑,代价为 c !bv(i, j) !bh(i, j),限制为 inf * (wh(i, j) + wv(i, j)),即不能涂过白色。

对于单点涂白,代价为 c bh(i, j) !wv(i, j) !wh(i, j) + c bv(i, j) !wh(i, j) !wv(i, j)。限制为 inf bh(i, j) bv(i, j),即不能涂超过。

这里看起来有三元关系,但是最优解里面同向不会涂超过两次,所以 bh(i, j) 为真的时候,wh(i, j) 也为真一定不优,可以把上式简化成 c bh(i, j) !wv(i, j),同理可以简化后面的,所有关系都是二元关系。

然后发现代数式里面有 x(u) x(v) 这样的项,这个是无法用最小割表示出的。但是观察发现只要把 bv, wh 的定义取反,所有的限制都变成 x(u) !x(v) 的项,可以直接最小割。

补充:在一般最小割问题中,展开后 x(u) * x(v) 项前面的系数是负的就可以最小割。

abc393_g

大概就是对偶一下,变成了一个带参的费用流问题。

经过一通分析,这个最优解会在一些分母不超过某个值的分数上取到,然后对这些离散的分数三分一下,三分之后的解用 primal dual 构造。

arc190_e

这显然是一个一般图匹配问题,所以直接跑 LP 可能会出 0.5。

根据一些 观察思考 猜结论对拍,连续的一段 0.5 需要向下取整,然后可以线段树维护 dp 了。

严谨的论证需要用到 Tutte-Berge formula,毛估估就是这一段分配的比较平均,没有单个数太小或者太大,但是解方程解出了小数,于是需要把这个 0.5 调整一下,根据不知道为啥,调整 0.5 就够了。

20250219 代码源 13

题 & 解

QOJ 9915

一看就只能 bitset,考虑如何 bitset。每个右端点,记录当前 l + r = x 的串是不是还是回文的,每次找到爆了的位置。

需要分块卡卡空间。

QOJ 9406

首先只需要考虑较小的大于最大的即可。不妨设 x >= y, z 并且 yz <= zy。枚举 x 和 x 的前缀 y 之后,是个二维数点问题。

ARC175 F

CF 1909G

考虑枚举 xy,然后查询后面一段的循环节,即 T = (x + y) + y ^ k + z。这个类似求阶可以直接做到 O(log n),但是要 hash,所以很难卡过去。

但是有神秘限制是 y <= LCS(x + y, y ^ k)。然后你滑窗的时候,可以利用这个性质,查新的 LCS 即可。最后还需要离线统计一下答案。

std 的做法比较精妙:我们直接枚举 y 的长度 q。首先有 x + y 在 lcp 里面,并且如果 x + y 可行,s 和 t 的下一位相同,那么 往后挪一位也是可行的。所以如果可行的话,区间的右端点一定是 lcp 的位置。对称的可以的到左端点一定是 lcs 的位置,也就是只要判断一个是否可行。

LOJ 6070

把区间不同子串的板子,搬到搞到 PAM 上就行了。

CF 1738H

贺上面的做法看起来不太能过。好像可以搞一个前端带删的 PAM,但感觉很容易写错。

有个比较暴力的做法是,每次删除开头最多删除一个回文串,即最长的。可以找到这个点,查询子树里面有没有出现过的,大概是个单点修改,区间最小值,以及需要一个倍增,倍增好像改成离线 dfs + 二分。

NOI 2023 字符串

大部分情况,直接比较对应的整个串就可以了,这个可以后缀排序之后二维数点。

回文串的时候会有反例,如果对着 l 直接做,那么可能需要一些 PAM 上的手法。但是枚举中间位置就是简明二维数点。

CF 2053G

感觉比较神秘。首先考虑如果分出来的没有公共循环节,如果没有的话,可以证明贪心匹配加反悔是可行的。

有的话解方程或者暴力即可。

时间复杂度为 O(m log m) 的。

QOJ 7742

没学会题解,摆烂了。

子串 Border 查询

经典问题,但感觉应该也有人不会。复习一下后缀树做法。

等价于找到最小的 p (l < p <= r),满足 lcp(l, p) >= r - p + 1。

即考虑 l 在后缀树上往上跳,等价于在子树里找到满足条件最小的 p,用用线段树合并之类的求出子树即可。但时间复杂度为 O(dep) 的。

考虑经典树链剖分,等价于要快速计算一条前缀的答案,并且只要在 O(链头子树大小) 复杂度完成就可以。然后离线从前往后插入每个挂的点。限制等价于 p + D[p] > r 并且 p > l 的最小值,在线段树上二分即可。

O(n log^2 n)。

CF 700E

首先只有后缀树上的节点是关键的,状态数被缩为 O(n),然后从上往下贪心即可,判断是简单的区间查询。

QOJ 9571

和上面一个题,反着的 border jump。

如果是回文串,至少可以做到一半,而不是回文串,因为第一步只能选不超过一半的,至多只有一半。所以操作的时候一旦变成回文串,就只会对回文串进行操作。

CF 1043G

板子检测题。

显然答案最多是 4,然后进行一个分类讨论。

CF 1817F

好像是基本子串结构板子题。考虑如果不会的话,也可以用一些标准的后缀树分析解决。

CF 917E

答案等于到 LCA 直链上的结果 + 拐弯的部分。直链上的结果相对简单,可以用 AC 自动机解决。拐弯的结果需要算出两边的 border 然后拼起来。

20250317-20250423

https://vjudge.net/article/8041

20250427 构造 & 计算几何 & 博弈论

CF1054G

CF1477D

UOJ750

UOJ771

P6644

CF1240F

P5549

DestructiveNim

FollowingNim & Sol

CF1033G

CF1646F

P9139

20250428 好题分享

at_joisp2025_d

CF1616G

at_agc040_e

UOJ919

20250502 图论

BZOJ4061

P9527

CF1307G

CF51F

AT_codefestival_2016_final_g

P9531

20250503 计数 & 贪心

P6789

P5296

P9600

P11051

UOJ455

20250504 字符串 & 数论 & 数据结构

P6292

LOJ6686

Gym103861F

20250507 Dp & sol

LOJ4164

QOJ6372

CF280E

QOJ7303

QOJ5357

AT_agc017_f