logo

yaohaoyou

春节

ZR暑假集训讲题

2026-08-03 Views 做题记录2957字15 min read

\Large{\color{red}\Diamond} 为重点转换步骤。

P15246 [WC2026] 猫和老鼠

感觉像是几个套路拼在一起的缝合题目,但我好像都无法快速识别。

先将这条数轴拉成一个平面图,x 轴是数轴,y 轴是时间,有左右边界 x=0x=0x=mx=m,那么 Jerry 需要从 (0,x)(0,x)(+inf,x)(+\inf,x'),而 Tom 需要通过若干条 (ai,ti)(bi,ti+biai)(a_i,t_i) \to (b_i,t_i+|b_i-a_i|) 的线段将这个平面图割开使 Jerry 无法通过。\Large{\color{red}\Diamond}

Tom 的线段都是斜率为 ±1\pm 1 的,Jerry 移动的斜率为 [1,1][-1,1],考虑将这个图顺时针旋转 45°45\degree 并扩大 2\sqrt2 倍(即将点 (x,y)(x+y,yx)(x,y) \to (x+y,y-x)),左右边界变成 y=xy=xy=x2my=x-2m。机器猫变成使用水平和竖直的线段将左右边界断开,有两种方式:

  1. 一条水平和竖直线段直接相交,阻止 Jerry 通过。
  2. 因为 Jerry 旋转后只能向右上(包含右和上)移动,所以可以使用两条不相交的线将 Jerry 的 x/y 坐标限制在一个区间中(如下图中红色线段是机器猫的不相交限制线段,Jerry 可以走绿色的路径,但到达了 ? 后就无法继续走)。

![](D:\yhy\Blog[WC2026] 猫和老鼠配图.png)

考虑刻画这样的限制,对于每条竖线,令上面的点是 in,下面的是 out,横线左边的是 in,右边的是 out。可以发现对于两种方式都能用以下方式刻画:inxoutxin_x \to out_x,对于满足 inxin_xoutyout_y 左上角的点连接 outyinxout_y \to in_x\Large{\color{red}\Diamond}若最后能从在 y=xy=x 的点到达 y=x2my=x-2m 的点,则经过的边的长度和就是 k=1k=1 时的答案。

继续拓展到 k>1k>1 的情况,要选出 kk 条不相交的,可以构建费用流模型 \Large{\color{red}\Diamond}

  1. SS 连向所有在 y=xy=x 上的点,容量为 11,费用为 00
  2. inxoutxin_x\to out_x 容量为 11,费用为 wxw_x
  3. outyinxout_y\to in_x 容量为 +/k+\infty / k,费用为 00
  4. 将所有在 y=x2my=x-2m 上的点连向 TT,容量为 11,费用为 00

答案就是这个图在流量为 kk 时的最小费用。注意 1144 的容量不是 +/k+\infty/k 是因为若在这个点重合时,Jerry 直接走到这个点只需要扣 11 的血量,而 33 是因为这条边只是虚构的边,实际画一下可以发现 Jerry 至少会扣两滴血量。

但是现在还是有 O(n2)\mathcal O(n^2) 条边,考虑优化建图,每个 outout 向左上角的 inin 连边,显然是一个二维偏序关系,使用主席树/可持久化树状数组优化即可。因为 flowflow 很小,使用原始对偶求费用流最后复杂度为 O(nklog2n)\mathcal O(nk\log^2n)

CF2097F Lost Luggage

好像应该之前讲过,但当时不会轮廓线 dp 就没改。

列出一个 m×nm\times n 的矩阵,其中 Gi,jG_{i,j} 表示第 ii 天机场 jj 剩余的行李数量。不难建出网络流模型:

  1. (i,j)(i+1,j1)(i,j) \to (i+1,j-1),容量为 ai,ja_{i,j}
  2. (i,j)(i+1,j)(i,j)\to (i+1,j),容量为 bi,jb_{i,j}
  3. (i,j)(i+1,j+1)(i,j)\to (i+1,j+1),容量为 ci,jc_{i,j}
  4. S(1,i)S\to(1,i),容量为 sis_i
  5. (k,i)T(k,i)\to T,容量为 ++\infty

kk 天的答案就是最大流,直接做复杂度是 O(nm3)\mathcal O(nm^3),无法通过。

考虑 nn 很小时的做法,因为最大流 = 最小割,所以可以考虑维护 nn 个点到 SS 的连通性来计算最小割。记 fi,j,S,0/1f_{i,j,S,0/1} 表示前 ii 行,目前到达 jj(i,[1,j)(i,[1,j)(i1,[j,n])(i-1,[j,n]) 的连通状态为 SS(i,j)(i,j) 是否连通 SS 的最小割。用轮廓线 dp 不难做到 O(nm2n)\mathcal O(nm2^n)

【UER #11】企鹅游戏

有结论:i=1mj=1n[ci,j>0]=O(L43)\sum_{i=1}^m\sum_{j=1}^n [c_{i,j}>0]=\mathcal O(L^\frac43),其中 ci,jc_{i,j} 表示 sjs_j 匹配 tit_i 的次数。证明:

所以若将 tit_i 放入 ss 构建的 AC 自动机中跑,只在成功匹配的 tt 中计数是能够接受的。建出一棵 endend 树,faxxfa_x \to x 表示 endpos(sfax)endpos(s_{fa_x})endpos(sx)endpos(s_x) 在 fail 树上最深的终点的祖先。对于每次询问 tt,将 tt 在 AC 自动机上匹配的 endposendpos 集合 SS 的所有点在 endend 树中暴力 dfs 子树并贡献答案即可,复杂度为 O(L43)\mathcal O(L^\frac43)

直接暴力 dfs 常数比较大,可以类似按照拓扑序,从原来加边的地方改成维护从下到上的链,常数较小可以通过。

P6640 [BJOI2020] 封印

最长公共子串考虑 SA。不难发现答案就是求 maxi=lrmin(ri+1,lcp(sufSi,sufTj))\displaystyle\max_{i=l}^r\min(r-i+1,lcp(sufS_i,sufT_j))。先把 S+#+TS+\#+T 拼起来,然后对于固定的 iilcp(sufSi,sufTj)lcp(sufS_i,sufT_j) 的最大值就是找 rkjrk_j 距离 rkirk_i 最近的属于 TTjj,只用找前面和后面即可。然后处理对 ri+1r-i+1 的限制,可以直接二分答案 xx,然后在 [l,rx+1][l,r-x+1] 中寻找最大的 lcp(sufSi,sufTj)lcp(sufS_i,sufT_j) 即可。复杂度为 O(nlogn+qlogn)\mathcal O(n\log n+q\log n)

OGF 入门题

给定 nnmm,你需要计数长度为 nn 的序列,每个数是 1,2,3,41,2,3,4 之一,满足 11 的数量减 22 的数量等于 mm

fi,j=fi1,j1+fi1,j+1+2fi1,j,f0,i=0Fi(x)=Fi1(x)(x+1x+2)Fn(x)=(x+1x+2)nans=[m](x2+2x+1x)nans=[n+m](x+1)2nans=[n+m]i=02n(2ni)xians=(2nn+m)f_{i,j}=\sum f_{i-1,j-1}+f_{i-1,j+1}+2f_{i-1,j},f_{0,i}=0 \\ F_i(x)=F_{i-1}(x)(x+\frac 1x+2) \\ F_n(x)=(x+\frac 1x+2)^n\\ ans=[m](\frac{x^2+2x+1}x)^n\\ ans=[n+m](x+1)^{2n} \\ ans=[n+m]\sum_{i=0}^{2n} \binom{2n}i x^i\\ ans=\binom{2n}{n+m}

P6624 [省选联考 2020 A 卷] 作业题

考虑拆开 val(T)val(T)

val(T)=(i=1n1wi)×gcd(w1,w2,,wn1)=(i=1n1wi)×dw1,dw2,dwn1φ(d)=dφ(d)[dw1dwn1]i=1n1wival(T)=(\sum_{i=1}^{n-1}w_i)\times \gcd(w_1,w_2,\dots,w_{n-1})\\ =(\sum_{i=1}^{n-1}w_i)\times \sum_{d|w_1,d|w_2,\dots d|w_{n-1}} \varphi(d) \\ =\sum_d \varphi(d)[d|w_1\wedge\dots\wedge d|w_{n-1}]\sum_{i=1}^{n-1}w_i\\

dd 的倍数的边拉出来做 Matrix-Tree 即可,但是还有问题就是矩阵树定理求解的是 wiw_i 的积的和,但我们需要求 wiw_i 的和。实际上 Matrix-Tree 的权值 wiw_i 不一定是常数,还可以是函数,所以将 wi=wix+1w'_i=w_ix+1,这样求出来的函数的一次项就是答案了\Large{\color{red}\Diamond}。做的过程只需要记录一次项和常数项即可,复杂度为 O(Vn3)\mathcal O(Vn^3),实际上准确的上界是 O(nmaxd(V)n3)\mathcal O(n\max d(V)n^3),可以通过。

AT_agc044_e Random Pawn

精妙的转化,积累一下套路。

首先不难发现可以在 maxai\max a_i 处断开,完成断环成链,移动至 a1=maxaia_1=\max a_i。令 fif_i 表示目前在 ii 的期望收益,不难列出方程fi=max(ai,fi1+fi+12bi)f_i=\max(a_i,\frac{f_{i-1}+f_{i+1}}2-b_i)。尝试将 bib_i 提出来做常数项,构造 gi=fi+dig_i=f_i+d_i\Large{\color{red}\Diamond}

gi=max(ai,fi1+fi+12bi)+digi=max(ai+di,gi1di1+gi+1di+12bi+di)gi=max(ai+di,gi1+gi+12di1+di+12di+2bi2)g_i=\max(a_i,\frac{f_{i-1}+f_{i+1}}2-b_i)+d_i \\ g_i=\max(a_i+d_i,\frac{g_{i-1}-d_{i-1}+g_{i+1}-d_{i+1}}2-b_i+d_i)\\ g_i=\max(a_i+d_i,\frac{g_{i-1}+g_{i+1}}2-\frac{d_{i-1}+d_{i+1}-2d_i+2b_i}2)\\

因为要让 max\max 后半部分的常数剔除,所以构造 di1+di+12di+2bi=0d_{i-1}+d_{i+1}-2d_i+2b_i=0,即 di=2bi1+2di1di2d_i=-2b_{i-1}+2d_{i-1}-d_{i-2},初始项随便设成 d0=d1=0d_0=d_1=0 即可。

gi=max(ai+di,gi1+gi+12)g_i=\max(a_i+d_i,\frac{g_{i-1}+g_{i+1}}2)

ai+dia_i+d_i 已经是常数了,考虑后面是一个类似取中点的形式,若将点 (i,gi)(i,g_i) 放到坐标系中,取后面的部分代表了 i1,i,i+1i-1,i,i+1 三点共线。但加上和常数取 max\max 时,发现会将 ii 的点往上提,会形成一个类似凸包的形态\Large{\color{red}\Diamond}。具体证明大概是 2gigi1+gi+12g_i\ge g_{i-1}+g_{i+1},即 gigi1gi+1gig_i-g_{i-1}\ge g_{i+1}-g_i,所以会形成一个下凸壳,注意有 an+1=a1a_{n+1}=a_1

AT_dwango2016qual_e 花火

好像依旧不太会 Slope Trick /ll

SiS_i 表示在 ii 时刻的烟花的位置集合,fi,jf_{i,j} 表示前 ii 时刻在 jj 的答案,不难列出 fi,j=mink=1jfi1,k+xSijxf_{i,j}=\min_{k=1}^j f_{i-1,k}+\sum_{x\in S_i}|j-x|。后面的 \sum 部分显然是下凸函数,然后可以归纳证明 Fi(x)=fi,jF_i(x)=f_{i,j} 也是下凸函数,考虑使用 Slope Trick。\Large{\color{red}\Diamond}

使用堆维护斜率拐点(经过堆中的拐点时斜率会 1-1),因为需要做前缀取 min\min,即将所有的斜率和 00min\min,考虑倒着维护从右往左的拐点。直接记录 k,bk,b 表示在 ++\infty 处的 F(x)=kx+bF(x)=kx+b,当加入 xp|x-p| 函数时,在 xpx\ge p 时会 kk+1,bbpk\gets k+1,b\gets b-p,到了 pp 处时还原成 pxp-x,即设置两个在 pp 处的拐点时 kk2,bb+2pk\gets k-2,b\gets b+2p

做完了加凸函数,然后再前缀取 min\min,直接从右往左走直到 k0k\le 0 时即可。复杂度 O(nlogn)\mathcal O(n\log n)。代码很好写,但理解了挺久的。

EOF