logo

yaohaoyou

节
春节

比赛题解

2025-07-10 Views 题解 | 做题记录3046字16 min read繁

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

typer

直接设 fi,jf_{i,j} 表示前 S[1∼i]S[1 \sim i] 匹配 T[1∼j]T[1\sim j] 位的答案。

fi,j=min⁡(fi−1,j+1,fi,j−1+1,fi−1,j−1+[Si=Tj])f_{i,j}=\min(f_{i-1,j}+1,f_{i,j-1}+1,f_{i-1,j-1}+[S_i\not=T_j])

直接做复杂度为 O(∣S∣m∣T∣)\mathcal O(|S|m|T|)。

由于 ∣T∣≤20|T|\le 20,并且发现 i−j≤fi,j≤i+ji-j\le f_{i,j}\le i+j,所以 i+j−fi,j≤2∣T∣i+j-f_{i,j}\le2|T|,由于值域范围小,所以套路性的将值域放在定义维上,将原本的 ii 定为 dp 值。◊\Large{\color{red}\Diamond}

设 gi,jg_{i,j} 为满足 fx,i=x+i−jf_{x,i}=x+i-j 最小的 xx。

上面的 ff 的转移式中前两种方法的 i+j−fi,ji+j-f_{i,j} 是不变的,所以先 gi,j←gi−1,jg_{i,j} \leftarrow g_{i-1,j}。

若想让 Si=TjS_i=T_j,gi,j←k(k>gi−1,j−2,Sk=Tj)g_{i,j} \leftarrow k(k>g_{i-1,j-2},S_k=T_j),否则 gi,j←k(k>gi−1,j−1,Sk≠Tj)g_{i,j} \leftarrow k(k>g_{i-1,j-1},S_k\neq T_j)。

预处理出每个位置 nxi,j,0/1nx_{i,j,0/1} 表示 SiS_i 后字符为/不为 jj 的第一个位置。

sum

本题保证了无重边自环。

k=1k=1 简单。

将 ∑f(S)2\sum f(S)^2 转成 ∑(f(S)2)\sum \binom{f(S)}2,赋予组合意义即为从 SS 的导出子图中任意选两条边的方案数的和,从而可以拆贡献至选取两条边进行计算。◊\Large{\color{red}\Diamond}

f(S)2=2(f(S)2)+f(S)f(S)^2=2\binom{f(S)}2+f(S)

两条边的情况可能是两条无交边或有一个公用顶点,分开讨论并枚举公共点即可。

f(S)3=6(f(S)3)+3f(S)2−2f(S)f(S)^3=6\binom{f(S)}3+3f(S)^2-2f(S)

f(S)2f(S)^2 和 f(S)f(S) 直接使用上面的即可,重点讨论 (f(S)3)\binom{f(S)}3 如何拆开。

影响结果的只有任选的三条边的点数 xx 和方案数 yy,贡献为 y2n−xy2^{n-x}。

x=3,4,5,6x={3,4,5,6}。由于总方案数为 (m3)\binom{m}3,所以 x=6x=6 可以直接用总的减去其它的计算。

x=3x=3,即一个三元环。直接用三元环计数即可,令方案数为 AA,复杂度为 O(mm)O(m\sqrt m)。

x=4x=4,可能是一条链或者一个菊花。

  • 链:枚举中间那一条边 (u,v)(u,v),方案数 B=(∑(degu−1)×(degv−1))−3AB=(\sum (deg_u-1)\times (deg_v-1))-3A,最后减 3A3A 是因为如果形成三元环,每条边都会被作为中间的边多算一次。
  • 菊花:枚举度数为 33 的点 uu,方案数 C=∑(degu3)C=\sum \binom{deg_u}{3}。

x=5x=5,即分离的一条三元链和一条边,枚举三元链的中心 uu,方案数 D=(∑(degu2)(m−2))−3A−2B−3CD=(\sum\binom{deg_u}2(m-2))-3A-2B-3C。

3A3A 因为三元环中三个点都会被作为链中心,2B2B 因为插入的新边可能在链的两端,3C3C 因为菊花的三条边都会被作为插入的新边。

x=6x=6,E=(m3)−A−B−C−DE=\binom m 3-A-B-C-D。

(f(S)3)=2n−3A+2n−4(B+C)+2n−5D+2n−6E\binom {f(S)}3=2^{n-3}A+2^{n-4}(B+C)+2^{n-5}D+2^{n-6}E。

sort

寻找第 kk 小可以先转化成二分答案 + 求有多少个 ≤mid\le mid。k←k−1k\leftarrow k-1

这里的字典序有些不同,可以直接用 AiA_i 记录 ii 出现的次数,比较 AA 和 BB 时从 i=1→ni=1\to n 比较 AiA_i 和 BiB_i 即可,若 Ai<BiA_i<B_i 则 A>BA>B,Ai>BiA_i>B_i 则 A<BA<B。

由于增加一个数一定会使字典序变小,所以 S[l,l]>S[l,l+1]>...>S[l,n]S[l,l]>S[l,l+1]>...>S[l,n] 且 S[1,r]<S[2,r]<...S[r,r]S[1,r]<S[2,r]<...S[r,r],于是对于左端点固定的区间具有单调性,设二分的区间是 [L,R][L,R],则可以通过双指针或二分对每个 ii 求出 MiM_i 使 S[i,n]<S[i,n−1]<...<S[i,Mi]≤S[L,R]S[i,n]<S[i,n-1]<...<S[i,M_i]\le S[L,R],进而求出 S[L,R]S[L,R] 的排名。◊\Large{\color{red}\Diamond}

若 rnk(S[L,R])≤krnk(S[L,R])\le k,则将 pri=Mi−1pr_i=M_i-1 表示删去 [i,Mi],[i,Mi+1]...[i,n][i,M_i],[i,M_i+1]...[i,n],并将 k←k−rnk(S[L,R])k\leftarrow k-rnk(S[L,R])。否则将 pli=Mipl_{i}=M_i 表示删去 [i,i],[i,i+1],...[i,Mi−1][i,i],[i,i+1],...[i,M_i-1]。

生成 [L,R][L,R] 时在剩余的所有区间中随机一个即可,期望每次能选到字典序排名的重点左右,所以复杂度是 O(log⁡n)O(\log n) 的。

双指针的过程就是有 O(n)O(n) 次加入和删除一个字符,并查询桶内第一个和 S[l,r]S[l,r] 的桶内的不同值。可以使用线段树维护 Ti=Ai−BiT_i=A_i-B_i,加入字符 cc 时将 Tc←Tc+1T_c\leftarrow T_c+1,删除时 Tc←Tc−1T_c \leftarrow T_c-1,查询时在线段树上二分或提前存储第一个 Ti≠0T_i\neq0,若 Ti>0T_i>0 则 A<BA<B,否则 A>BA>B。总复杂度为 O(nlog⁡2n)O(n\log^2n)。

countcircle

设 Li,j,Ri,j,Ui,j,Di,jL_{i,j},R_{i,j},U_{i,j},D_{i,j} 分别表示 (i,j)(i,j) 向左,向右,向上,向下能走到的最远的位置。

原题就是求

∑i=1n∑j=1m∑x=Uii−1∑y=Ljj−1[Dx,y≥i∧Rx,y≥j]\sum_{i=1}^n\sum_{j=1}^m\sum_{x=U_i}^{i-1}\sum_{y=L_j}^{j-1}[D_{x,y}\ge i\wedge R_{x,y}\ge j]

明显上面的式子是四维的,无法直接做。将矩阵进行分治,选择竖着的中线 midmid,分别对左右独立讨论经过中线的方案数再乘起来,将四维转换为三维。◊\Large{\color{red}\Diamond}

两边情况相似,只考虑左侧穿过中线的情况。先枚举 u∈[1,n],v∈(u,n]u\in[1,n],v\in (u,n],计算左侧选取的 匚 的数量。

countcircle配图

于是现在只要求

∑u=LR∑v=u+1R∑x=max⁡(l,Lu,mid,Lv,mid)mid−1[Du,x≥v]\sum_{u=L}^R\sum_{v=u+1}^R\sum_{x=\max(l,L_{u,mid},L_{v,mid})}^{mid-1}[D_{u,x}\ge v]

枚举完 u,vu,v 后分类讨论 max⁡(l,Lu,mid)\max(l,L_{u,mid}) 和 max⁡(l,Lv,mid)\max(l,L_{v,mid}) 哪个更大,若前者更大,则对于所有 uu 询问的区间已经固定,所以只要开一个桶记录 Du,xD_{u,x} 的后缀个数和。如果是后者更大,就相当于求 ∑x=max⁡(l,Lv,mid)mid−1[Uv,x≤u]\displaystyle\sum_{x=\max(l,L_{v,mid})}^{mid-1}[U_{v,x}\le u],处理方式和上面类似,开另一个桶记录 Uv,xU_{v,x} 的前缀个数和。这样就能单次 O(1)O(1) 解决。

设 len=r−l+1,LEN=R−L+1len=r-l+1,LEN=R-L+1,这样单次的复杂度为 O(LEN2+len×LEN)\mathcal O(LEN^2+len\times LEN),由于分治时面积每次一定会减半,所以递归层数为 O(log⁡2nm)\mathcal O(\log_2nm)。若能保证 LEN≤lenLEN\le len 则单次复杂度为 O(len×LEN)\mathcal O(len\times LEN),此时总复杂度正确。每次递归后若 LEN>lenLEN>len 则从 [l,r][l,r] 中间取中线变为从 [L,R][L,R] 中间取中线,复杂度为 O(nmlog⁡2nm)\mathcal O(nm\log_2nm)。

frame

多树问题和距离问题考虑点分治和点分树。

点分树的性质:原树上 u,vu,v 的路径会经过点分树上的 LCA(u,v)LCA(u,v),所以 dis(x,y)=dis(x,LCA′(x,y))+dis(LCA′(x,y),y)dis(x,y)=dis(x,LCA'(x,y))+dis(LCA'(x,y),y),LCA′LCA' 表示在点分树上的 lca。◊\Large{\color{red}\Diamond}

考虑对第一棵树进行点分治,若当前分治中心为 rtrt,已经处理过的点集为 SS,当前需要求 uu 到 SS 的答案。设 ii 以 rtrt 为根的深度为 aia_i,则需要求 min⁡v∈Sau+av+dis2(u,v)\min_{v\in S} a_u+a_v+dis_2(u,v),由点分治的性质可得

\min_{v\in S} a_u+a_v+dis_2(u,v)=\min_{v\in S}a_u+a_v+dis_2(u,LCA_{2'}(u,v))+dis_2(LCA_{2'}(u,v),v) \\ =\min_{v\in S,x=LCA_{2'}(u,v)}(a_u+dis_2(u,x))+(a_v+dis_2(v,x)) & \Large{\color{red}\Diamond}

xx 为点分树上 uu 和 vv 的祖先,所以 xx 只有 O(log⁡2n)\mathcal O (\log_2n) 个,当将 vv 加入 SS 时,跳过 vv 的每个祖先 xx 并将 av+dis2(v,x)a_v+dis_2(v,x) 的贡献挂在 xx 上,uu 查询时只要将挂在所有祖先的贡献加上 au+dis2(u,x)a_u+dis_2(u,x) 后求最大值即可,若 u,vu,v 在 xx 的同一颗子树内,则长度只会更大,不影响最小值更新。

复杂度为 O(nlog⁡2n)\mathcal O(n\log^2n),瓶颈在点分治和在点分树上跳祖先。

岁月

正难则反。先容斥一下,考虑计算有多少方案使得没有一个点能被 1,21,2 同时到达。◊\Large{\color{red}\Diamond}

令 fSf_S 表示只保留 SS 导出子图并给其定向,11 恰好能到达 x∈Sx\in S 的方案数,gSg_S 和 fSf_S 同理,从 22 号点出发,w(S)w(S) 表示 SS 的导出子图的边数。

ans=2m−∑S∩T=∅fSgT2w(U−S−T)ans=2^m-\sum_{S \cap T=\empty}f_Sg_T2^{w(U-S-T)}

由于 S∩T=∅S\cap T=\empty,所以只需枚举 T⊆U−ST\sube U-S 即可,复杂度为 O(3n)\mathcal O(3^n)。

思考如何求 f,gf,g,同样用总方案数 2w(S)2^{w(S)} 减去不合法的。

先枚举 T⊂ST\sub S,计算只能到达 TT 的方案数。内部可达为 fTf_T,外部 S−TS-T 的导出子图随意,一条边 (u,v),u∈T,v∈S−T(u,v),u\in T,v\in S-T 的只能定向为 (v,u)(v,u),所以方案数为 2w(S−T)fT2^{w(S-T)}f_T,枚举子集复杂度也是 O(3n)\mathcal O(3^n)。

总复杂度为 O(3n)\mathcal O(3^n)。

EOF