logo

yaohaoyou

春节

寒假比赛

2026-01-30 Views 做题记录8896字42 min read

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

typer

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

fi,j=min(fi1,j+1,fi,j1+1,fi1,j1+[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(SmT)\mathcal O(|S|m|T|)

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

gi,jg_{i,j} 为满足 fx,i=x+ijf_{x,i}=x+i-j 最小的 xx

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

若想让 Si=TjS_i=T_jgi,jk(k>gi1,j2,Sk=Tj)g_{i,j} \leftarrow k(k>g_{i-1,j-2},S_k=T_j),否则 gi,jk(k>gi1,j1,SkTj)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)22f(S)f(S)^3=6\binom{f(S)}3+3f(S)^2-2f(S)

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

影响结果的只有任选的三条边的点数 xx 和方案数 yy,贡献为 y2nxy2^{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=((degu1)×(degv1))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)(m2))3A2B3CD=(\sum\binom{deg_u}2(m-2))-3A-2B-3C

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

x=6x=6E=(m3)ABCDE=\binom m 3-A-B-C-D

(f(S)3)=2n3A+2n4(B+C)+2n5D+2n6E\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 midkk1k\leftarrow k-1

这里的字典序有些不同,可以直接用 AiA_i 记录 ii 出现的次数,比较 AABB 时从 i=1ni=1\to n 比较 AiA_iBiB_i 即可,若 Ai<BiA_i<B_iA>BA>BAi>BiA_i>B_iA<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,n1]<...<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=Mi1pr_i=M_i-1 表示删去 [i,Mi],[i,Mi+1]...[i,n][i,M_i],[i,M_i+1]...[i,n],并将 kkrnk(S[L,R])k\leftarrow k-rnk(S[L,R])。否则将 pli=Mipl_{i}=M_i 表示删去 [i,i],[i,i+1],...[i,Mi1][i,i],[i,i+1],...[i,M_i-1]

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

双指针的过程就是有 O(n)O(n) 次加入和删除一个字符,并查询桶内第一个和 S[l,r]S[l,r] 的桶内的不同值。可以使用线段树维护 Ti=AiBiT_i=A_i-B_i,加入字符 cc 时将 TcTc+1T_c\leftarrow T_c+1,删除时 TcTc1T_c \leftarrow T_c-1,查询时在线段树上二分或提前存储第一个 Ti0T_i\neq0,若 Ti>0T_i>0A<BA<B,否则 A>BA>B。总复杂度为 O(nlog2n)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=1nj=1mx=Uii1y=Ljj1[Dx,yiRx,yj]\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=LRv=u+1Rx=max(l,Lu,mid,Lv,mid)mid1[Du,xv]\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)mid1[Uv,xu]\displaystyle\sum_{x=\max(l,L_{v,mid})}^{mid-1}[U_{v,x}\le u],处理方式和上面类似,开另一个桶记录 Uv,xU_{v,x} 的前缀个数和。这样就能单次 O(1)O(1) 解决。

len=rl+1,LEN=RL+1len=r-l+1,LEN=R-L+1,这样单次的复杂度为 O(LEN2+len×LEN)\mathcal O(LEN^2+len\times LEN),由于分治时面积每次一定会减半,所以递归层数为 O(log2nm)\mathcal O(\log_2nm)。若能保证 LENlenLEN\le len 则单次复杂度为 O(len×LEN)\mathcal O(len\times LEN),此时总复杂度正确。每次递归后若 LEN>lenLEN>len 则从 [l,r][l,r] 中间取中线变为从 [L,R][L,R] 中间取中线,复杂度为 O(nmlog2nm)\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)LCALCA' 表示在点分树上的 lca。\Large{\color{red}\Diamond}

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

minvSau+av+dis2(u,v)=minvSau+av+dis2(u,LCA2(u,v))+dis2(LCA2(u,v),v)=minvS,x=LCA2(u,v)(au+dis2(u,x))+(av+dis2(v,x))\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 为点分树上 uuvv 的祖先,所以 xx 只有 O(log2n)\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,vxx 的同一颗子树内,则长度只会更大,不影响最小值更新。

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

岁月

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

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

ans=2mST=fSgT2w(UST)ans=2^m-\sum_{S \cap T=\empty}f_Sg_T2^{w(U-S-T)}

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

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

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

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

快速傅里叶变换

其实还有 君子兰double

可以直接对差分后的数组 cc 进行计数。令 ci=aiai1c_i=a_i-a_{i-1}bbcc 排列后的数组,则 b,cb,c 可以与 aa 一一映射当且仅当 bi>0,cici+1\forall b_i>0,c_i\le c_{i+1}bi=cim\sum b_i=\sum c_i\le m\Large{\color{red}\Diamond}

由于期望的线性性,最后做一次前缀和是不需要的,只要求出 E(bi)E(b_i) 后再做一次前缀和即可,即 E(j=1ibj)=j=1iE(bj)E(\sum_{j=1}^i b_j)=\sum_{j=1}^iE(b_j)。对于每个位置 ii 单独考虑,E(bi)=j>0(j×P(bi=j))=j>0P(bij)E(b_i)=\sum_{j>0}(j\times P(b_i=j))=\sum_{j>0} P(b_i\ge j),这一步就是阶梯化贡献。若 bijb_i\ge jki,bkj\forall k\ge i,b_k\ge j,所以就是求出 cc 中有至少 ni+1n-i+1 个数 j\ge j 的概率,转成求方案数后使用二项式反演做容斥。钦定有 ii 个数 j\ge j 的方案数为 (ni)(mi(j1)n)\binom{n}{i}\binom{m-i(j-1)}{n},所以恰好有 ii 个数 j\ge j 的方案数就是 k=in(1)ki(ki)(nk)(mk(j1)+nn)\sum_{k=i}^n(-1)^{k-i}\binom{k}{i}\binom{n}{k}\binom{m-k(j-1)+n}{n}。因为只有 (1)ki(-1)^{k-i} 中有 ii,所以可以先预处理出 fi=j=1m(ni)(mi(j1)+nn)f_i=\sum_{j=1}^m\binom{n}{i}\binom{m-i(j-1)+n}{n},然后做容斥的时候再枚举 k[1,n]k\in [1,n] 求出的是恰好,最后再做一次后缀和得到至少。复杂度为 O(n2+mlnm)\mathcal O(n^2+m\ln m)

奖金

题意:

给定一个长度为 2n12n-1 的数组的所有奇数位的值,在偶数位填入数,使得最大子段和-最大非负区间和最大,非负区间表示一个区间内的所有数都是非负数。所有数的权值都要在 [k,k][-k,k] 中。

题解:

令最大子段和区间为 [l,r][l,r],最大非负区间为 [L,R][L,R]。若不是 lLRrl\le L \le R\le r,则可以将 [L,R][L,R] 不在 [l,r][l,r] 部分的所有偶数位都填为 1-1,可以使答案更优,所以必然满足 lLRrl\le L\le R\le r。若填入 0x<k0\le x< k,讨论 xx 所在位置不难发现将 xx+1x\gets x+1 一定不劣,所以偶数位只会填入 1/k-1/k\Large{\color{red}\Diamond}

l>2l>2,则可以将 [2,l)[2,l) 的所有偶数位都填成 kk,由于值域上界为 kk,所以将 l1+[a1<0]l\gets 1+[a_1<0] 时补入的区间最大后缀和 mxmx 一定 0\ge 0,此时最大子段和加 mxmx,最大非负区间和至加 mxmx,所以对答案一定不劣,同理 rn[an<0]r\gets n-[a_n<0]\Large{\color{red}\Diamond}

然后开始 dp,令 fi,jf_{i,j} 表示前 ii 个位置填了 jj1-1 时最小的 sum[L,R]sum[L,R],求答案时枚举 jj,然后可以求出填了多少个 kk,最大子段和就是 sum[1+[a1<0],n[an<0]]sum[1+[a_1<0],n-[a_n<0]]

fi,j=mink=0i1{max(fk1,j1,sum(k+1,i)kmod2=0max(fk1,j,sum(k+1,i))kmod2=1(x[k+1,i],ax0)f_{i,j}=\min_{k=0}^{i-1} \begin{cases} \max(f_{k-1,j-1},sum(k+1,i) & k\bmod 2 =0 \\ \max(f_{k-1,j},sum(k+1,i)) & k \bmod 2 =1 \end{cases} (\forall x\in [k+1,i],a_x\ge 0)

现在直接做是 O(n3)\mathcal O(n^3)。优化考虑将 max\max 拆开,由于显然 fi,jf_{i,j} 对于固定的 jjii 越大 fi,jf_{i,j} 单调不减,sum(k+1,i)sum(k+1,i) 也是单调不增,所以可以双指针直接找到 max\max 的转折点,然后就是 O(n2)\mathcal O(n^2)。代码实现时为了方便将 fi,jf_{i,j} 两维交换了,存储在 fj,if_{j,i} 了。

感觉像脑电波题。赛时一步都想不出来。

首先观察到单次操作后 Xi,j=(Ai1,j+Ai,j1+Ai+1,j+Ai,j+14Ai,j)/2X_{i,j}=(A_{i-1,j}+A_{i,j-1}+A_{i+1,j}+A_{i,j+1}-4A_{i,j})/2 会呈现为操作点的 X=2X=2,经过操作点的两条对角线上的点 X=1X=1,其余都 X=0X=0\Large{\color{red}\Diamond}

然后就是比较套路了。令 BB 矩阵为对应点是否被选择的矩阵(即所求的矩阵),将 Bi,jPi+jB_{i,j} \to P_{i+j}Bi,jQijB_{i,j} \to Q_{i-j},即 PPQQ 为主副对角线上 B 的和。不难发现 P,QP,Q 的奇偶位是独立的,并且都满足 imod2=oPi=imod2=oQi(o={0,1})\sum_{i\bmod 2=o} P_i=\sum_{i\bmod2=o} Q_i(o=\{0,1\})这里获得了两条方程)。

接下来询问形如 Pi+j+Qij=Xi,jP_{i+j}+Q_{i-j}=X_{i,j} 的等式,由于将所有的 PiPixP_i\gets P_i-xQiQi+xQ_i\gets Q_i+x 也不会影响所有的等式成立。所以看似有 (n+1)2(n+1)^2 条方程,但实际上只有 4n44n-4 条本质不同的方程,再加上上面的 22 条共有 4n24n-2 条方程,而刚好也有 4n24n-2 个未知数,只要设参然后代入就能求出 P,QP,Q。打表手玩后发现只要将含 Pn,P1+n,Q0,Q1P_n,P_{1+n},Q_0,Q_1 的方程列完就刚好足够。

考虑将网格图转成二分图\Large{\color{red}\Diamond}。将 Bi,j=1B_{i,j}=1 视为 L(i+j)R(ij)L(i+j)\lrarr R(i-j),则此时左右部点的度数序列分别就是 P,QP,Q,但是这个二分图会有限制左部点只能连向一个右部点区间(只会包含)。需要构造方案就直接将左部点能到达的区间长度排序,贪心尽量当前左部点连向 QQ 中区间最大的点即可,需要用线段树维护,所以总复杂度为 O((n+k)logn)\mathcal{O}((n+k)\log n)

pingpong

赛时。

多次询问是假的,直接离线排序。首先 freq106\sum freq\le 10^6 是好做的,只要花费 O(logn)\mathcal{O}(\log n) 的时间消掉一个网即可。正解考虑优化这个过程,首先会处理左右端点有多个相同位置的网的情况,直接可以 O(1)\mathcal{O}(1) 消掉一个位置所有的网,然后每次就可以花费 O(logn)\mathcal{O}(\log n)TTdis,disdis+1T\gets T-dis,dis\gets dis+1,所以只会有 O(T)\mathcal{O}(\sqrt T) 种坐标,将所有完全相同的网合并后,每种网只会出现 O(Tleni)\mathcal{O}(\frac{\sqrt{T}}{len_i}) 次,所以总和为 O(TlnT)\mathcal{O}(\sqrt T\ln \sqrt T),复杂度是 O((N+T)(logN+lnT)+QlogQ)\mathcal{O}((N+\sqrt T)(\log N+\ln \sqrt T)+Q\log Q)

select

赛后。感觉 O(n2)\mathcal{O}(n^2) 和正解没有任何关系啊,不会分治还是太菜了。

首先是即使没有观察到性质也应该想到 O(nlog2n)\mathcal{O}(n\log^2n) 的分治做法。分治后钦定第一个区间一定要过 midmid,离线掉一维后就只要做对于 bb 数组的每种选择 [l2,r2][l_2,r_2] 找到包含 midmid 的极长合法段 \Large{\color{red}\Diamond}。首先 bl21b_{l_2-1}br2+1b_{r_2+1} 显然只会是与当前分治区间 a[l,r]a[l,r] 颜色相同的点或 l2=1/r2=ml_2=1/r_2=m,否则扩展后一定更优,于是也可以将 bb 数组删到只剩 rl+1r-l+1 个。

[l2,r2][l_2,r_2] 是二维状态,考虑对 r2r_2 扫描线,同时数据结构在 l2l_2 维护 [l2,r2][l_2,r_2] 的状态。对于 bb 选择 [l2,r2][l_2,r_2],维护 [L,R](LmidR)[L,R](L\le mid\le R) 表示 a[L,R]a[L,R] 是与 b[l2,r2]b[l_2,r_2] 不重的极大区间,显然对于同一个 r2r_2,随着 l2l_2 增大对应的 LL 单调不增,RR 单调不减,所以可以使用类似单调栈的思路解决。当 r2r2+1r_2\gets r_2+1,令 br2=axb_{r_2}=a_x,若 xmidx\le mid,所有的 LLxxmax\max。若 xmidx\ge mid,所有的 RRxxmin\min,刚好对应一段后缀,单调栈维护即可,过程中需要做区间加求区间最值,总复杂度 O(nlog2n)\mathcal{O}(n\log^2 n)

考虑用性质优化,首先显然答案至少为 max(x,y)\max(\sum x,\sum y),而最后的答案为 x[l1,r1]+y[l2,r2]x[l_1,r_1]+y[l_2,r_2],所以一定有 x[l1,r1]>x2x[l_1,r_1]>\frac{\sum x}2y[l2,r2]>x2y[l_2,r_2]>\frac{\sum_x}2,否则还不如全选一个区间,所以找到最小的 i=1pxix2\sum_{i=1}^px_i\ge\frac{\sum x} 2i=1qyqy2\sum_{i=1}^q y_q\ge\frac{\sum y}2,则一定有 [l1,r1][l_1,r_1] 跨过 pp[l2,r2][l_2,r_2] 跨过 qq,然后就不用分治和去重了,把 p,qp,q 当作上面的 midmid 做即可,复杂度为 O(nlogn)\mathcal{O}(n\log n)

区间

赛后。这个也太抽象了,第一步都想不到。

首先有个显然的性质,一次取肯定会取完一个 LDS,所以可以考虑直接将 LDS 缩起来。(这个是赛时想到的)

然后就是将这个思路继续拓展。实际上,由于一个LDS内的选取顺序一定是连续的,所以影响他们什么时候取的就只有平均数(总和)了 \Large{\color{red}\Diamond},所以对于相邻同侧的两个块 (s1,len1)(s_1,len_1)(s2,len2)(s2,len_2) 只要满足 s1len1s2len2\frac{s_1}{len_1}\ge \frac{s_2}{len_2} 就一定会取完第一个块后立刻取第二个块(因为平均值拼上会更大),所以直接将两个块合并。此刻,kk 左右两侧的块就会分别单调了,即平均值形成 \k/ 的样子,对于先选左边和先选右边做差后能证明先选平均值更小的一定更优,所以直接将左右的块组成的序列归并就能得到操作顺序了。

现在需要一个数据结构,支持增删区间,维护排序后的带系数的全局贡献和,直接使用平衡树维护,插入删除对其他贡献系数的影响求区间和即可。也可以提前将所有的单调栈的块信息预处理后按平均值离散化后在线段树上做单点修区间求和,复杂度 O(nlogn)\mathcal{O}(n\log n)

序列

赛后。其中 O(nnα(n))\mathcal{O}(n\sqrt n\alpha(n))O(nlogn)\mathcal{O}(n\log n) 的做法都在代码源的题解中亦有记载,不改题导致的。

首先 O(nnlogn)\mathcal{O}(n\sqrt n \log n) 的做法很显然,如果使用莫队尝试根号平衡。这个应该是比较套路的做法了,使用回滚莫队后,如果右端点只有向右移动,则每次就类似于初始时 bi=ib_i=-i,给后缀加一,求最后一个 0\ge 0 的位置。考虑使用单调栈维护后缀最大值,每次增加 [x,n][x,n] 就找到 xx 在单调栈中的前驱后继(包括 xx),然后将前驱删除,这个过程不难用链表+并查集维护。然后考虑左端点也可能会乱动,如果暴力撤销单调栈和链表会影响复杂度均摊,所以考虑和询问平衡复杂度。

考虑对值域分块,维护每个块内的后缀最大值(单调栈),后缀加 [x,n][x,n] 的时候会将 xx 所在块分裂,只要使用上面的链表+并查集维护单调栈即可,然后剩余的块直接在 idx+1id_x+1 打上差分标记即可,询问时再做前缀和。比较妙的是可以提前将 ala_ln\sqrt n 种取值也作为分块的端点,这样所有的后缀加/减都只要打差分标记了,不会因为维护单调栈而影响均摊。查询的时候先找到答案在那个块后在块中跑单调栈即可,总复杂度为 O(nnα(n))\mathcal{O}(n\sqrt n\alpha(n))

另一种做法就是让 xxnn11,由于对于 [l1,r1][l2,r2],ans[l1,r1]ans[l2,r2][l_1,r_1]\sube [l_2,r_2],ans[l_1,r_1]\le ans[l_2,r_2],所以可以在求出 ans[l2,r2]ans[l_2,r_2] 前忽略 [l1,r1][l_1,r_1],这样当前的询问区间就是互不相交的,所以左右端点分别递增,可以使用线段树维护后缀加,当确定一个 ans[l,r]=xans[l,r]=x 时,将 [l,r][l,r] 删除,然后在线段树上二分来加入新的极长询问区间。复杂度 O(nlogn)\mathcal{O}(n\log n)

染色

fTf_T 表示 g(c,S)=Tg(c,S)=T 的方案数。

ans=T=g(c,S)fTTk=SfSi=1k(Si)i!{ki}=i=1ki!\{ki\}SfS(Si)ans=\sum_{T=g(c,S)}f_T|T|^k\\ =\sum_{S}f_S\sum_{i=1}^k\binom{|S|}{i}i!\left\{{k\atop i}\right\} \\ =\sum_{i=1}^ki! {k \brace i}\sum_{S} f_S\binom{|S|}i

考虑 (Si)\binom{|S|}i 的意义是在 SS 中选 ii 种颜色的方案数,则可以转为枚举选出后的集合 TS,T=iT\sube S,|T|=i,令 gT=TSfSg_T=\sum_{T\sube S} f_S,则 ans=i=1ki!\{ki\}T=igTans=\sum_{i=1}^ki! {k \brace i}\sum_{|T|=i} g_T。由于颜色集合无标号,所以可以令 gS=gT,S=Tg_{S}=g_{T},|S|=|T|,令 hi=gS,S=ih_i=g_S,|S|=i,则 ans=i=1ki!\{ki\}(mi)hians=\sum_{i=1}^ki! {k \brace i}\binom{m}{i}h_i

考虑求 hhhih_i 表示 [1,i]g(c,S)[1,i]\sube g(c,S) 的方案数,正着不好求,考虑容斥,令 did_i 表示钦定选的都是 >i>i 的方案数,则二项式反演得 hi=j=0i(1)j(ij)djh_i=\sum_{j=0}^i(-1)^j\binom{i}{j}d_j。做 did_i 可以直接简单 dp 转移。总复杂度 O(nk+k2)\mathcal{O}(nk+k^2)

原神,启动!

整数序列

没想到做闵可夫斯基和。

f(x)f(x) 表示恰好分 xx 段的答案,显然 f(x)f(x) 是一个上凸包。考虑对于一个线段树区间 [l,r][l,r] 暴力维护出长度为 rl+1r-l+1ff 函数,合并的时候就是做 (max,+)(\max,+) 卷积,由于两个函数都是凸的,所以直接归并差分数组即可(闵可夫斯基和)\Large{\color{red}\Diamond}

然后每次询问就是有 O(logn)\mathcal{O}(\log n) 个凸包,求出他们合并后的第 kk 项。直接合并就 O(n)\mathcal{O}(n) 了,可以 wqs 二分后在每个凸包中再二分求出交点,复杂度为 O(nlogn+qlog2nlogV)\mathcal{O}(n\log n+q\log^2 n\log V)

实际上可以将最后一个求交点的二分离线下来做一次整体二分,复杂度优化到 O(nlogn+qlognlogV)\mathcal{O}(n\log n+q\log n\log V)

2026 省选模拟赛 Day 17 #B. 追忆

假的追忆,但更困难了。

首先这个题的空间是开不下 O(n2)\mathcal{O}(n^2) 的 bitset 的,但是由于只需要求可达的集合大小,所以可以类似将 [1,n][1,n] 按照 BB 分块\Large{\color{red}\Diamond},每次只求到达一个块内元素的可达性,空间为 O(nB)\mathcal{O}(nB),时间为 O(n2ω+n2B)\mathcal{O}(\frac{n^2}\omega+\frac{n^2}B),只要将 BB 开到刚好卡到空间限制就基本不会对时间复杂度有影响。

其实这个矩阵内的点是假的,就算开到空间内的点/k 维偏序也只是常数上的区别,因为都已经有 O(n2ω)\mathcal{O}(\frac{n^2}\omega) 的复杂度了就不用考虑怎么拆多维偏序了,直接对于每一维求出在询问区间内的点的集合,然后全部 & 起来就是满足的集合。需要求满足的点的可达集合,就可以先对每个点 uu 记录 bsu,ibs_{u,i} 表示 uu 是否在第 ii 个询问中,然后转移时跑拓扑排序,将 uu 可达的点 tt 都做 bstbstbsubs_t\gets bs_t \vee bs_u 表示 tt 会贡献到询问 ii \Large{\color{red}\Diamond}

现在有一个 n×qn\times qbitset 记录了 bsu,ibs_{u,i} 表示 uu 是否会贡献到询问 ii,若把其当成一个 01 矩阵,则第 ii 个询问的答案就是第 ii 列的和。考虑 诡异操作 的 trick,记录 cnti,jcnt_{i,j} 表示第 ii 列的和的第 jj 个二进制位,然后将 cntcnt 转置后就变成了一个 log2n×q\log_2n \times q 的矩阵,每次做对两个矩阵的每一行依次做二进制加法,单次复杂度为 O(qlognω)\mathcal{O}(\frac{q\log n}\omega),做 nn 次加法复杂度就是 O(nqlognω)\mathcal{O}(\frac{nq\log n}{\omega})。但是可以使用分治将 logn\log n 进一步减小,具体的,每次递归求解 [l,mid][l,mid][mid+1,r][mid+1,r] 的和,再做一次加法,复杂度 T(n)=2T(n2)+O(qlognω)T(n)=2T(\frac n2)+\mathcal{O}(\frac{q\log n}\omega),由主定理可以得到 T(n)=O(nqω)T(n)=\mathcal{O}(\frac{nq}\omega),虽然都是做 n1n-1 次加法,但分治可以将 logn\log n 不卡满,所以复杂度少一个 log\log。总复杂度为 O(nqω)\mathcal{O}(\frac{nq}\omega),需要使用第一段的卡空间方法,将 qq 次询问分块处理,平衡后时间复杂度做到 O(nqω+qB)\mathcal{O}(\frac{nq}\omega+qB),空间 O(nBω)\mathcal{O}(\frac{nB}\omega)

Cyberangel

考虑分治,将当前区间离散化成值域为 [1,siz][1,siz],这一步可以每次桶排后递归,可以做到单 log\log。尝试通过扫值域上的 limlim 后求解所有跨过 [mid,mid+1][mid,mid+1] 的区间的当前贡献和。若当前只保留 lim\le lim 的元素,则当前的数能在 [l,r][l,r] 产生贡献当且仅当其为 [l,r][l,r] 的最大值,分类讨论一下即可拆贡献。

  • 只保留 [l,mid][l,mid] 的后缀最大值,令其为数组 bb,则 bib_i 的贡献为 abi×(bibi1)×(Rimid1)a_{b_i}\times(b_i-b_{i-1})\times (R_i-mid-1),其中 RiR_i[mid+1,r][mid+1,r] 最左边的 >abi>a_{b_i} 的位置,b0=l1b_0=l-1

  • 只保留 [mid+1,r][mid+1,r] 的后缀最大值,令其为数组 cc,则 cic_i 的贡献为 aci×(ci+1ci)×(midLi)a_{c_i}\times(c_{i+1}-c_i)\times (mid-L_i),其中 LiL_i[l,mid][l,mid] 最右边的 aci{\color{red}{\ge}}a_{c_i} 的位置,cc 的最后一项始终为 r+1r+1

对于新加入的 ax=lima_x=lim,不妨设 x[l,mid]x\in [l,mid],则需要操作:

  1. bi[l,x)b_i\in [l,x)bib_i 移除并删除贡献。
  2. Li<xL_i<xLixL_i\gets x 并重新计算贡献。
  3. xx 插入 bb 的开头并更新 b1b_1b2b_2 的贡献。

不难发现 2 操作前原本的 LiL_i 就是 1 操作时移除的,所以可以尝试将 2 操作和 1 操作放在一起做。具体的,可以维护 midl+1mid-l+1vector,其中 veci={jLj=i}vec_i=\{j|L_j=i\},操作 1,2 就是将所有 bi<xb_i<xvecbivec_{b_i} 合并至 vecxvec_x 并重新计算贡献,同时记录 si=jveciacj×(cj+1cj)s_i=\sum_{j\in vec_i} a_{c_j}\times(c_{j+1}-c_j),贡献就是 si×(midi)s_i\times (mid-i)。由于 3 操作中更新 c2c_2 的贡献和 1 操作的删除贡献需要重新查询 LiL_i,但查询前驱直接做至少要单 log\log,所以应该在 1,2 操作时直接在合并时更新 LiL_i。实际上,动态维护 LiL_i 只需要支持合并和单点查询,所以不需要使用 vector,直接用并查集就可以做到单次查询 O(α(n))\mathcal{O}(\alpha(n))

至此,我们已经完成了 3 种操作,对于 x(mid,r]x\in (mid,r] 的情况类似。总复杂度为 O(nlognα(n))\mathcal{O}(n\log n\alpha(n))

EOF