专栏文章

题解:P7722 [Ynoi2007] tmpq

P7722题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@mio9emkk
此快照首次捕获于
2025/12/02 15:31
3 个月前
此快照最后确认于
2025/12/02 15:31
3 个月前
查看原文

前言

这篇题解是 zak 的做法,我实现得很丑所以常数巨大,但我尽量把我的实现讲清楚()。

做法

转化 & 暴力

首先,令 bi=bai,ci=caib'_i=b_{a_i},c'_i=c_{a_i},就可以将原题条件转换为 bi=ai=cib'_i=a_i=c'_i,那么对 aia_i 进行单点修改,其实就相当于对 bib'_icic'_i 都进行单点修改。
对于每一种 bi=ai=ci=wb'_i=a_i=c'_i=www,他们的答案数是互相独立互不干扰的,所以可以对每种 ww 单独考虑对答案的贡献。
dpi,1/2/3dp_{i,1/2/3} 表示考虑前 ii 个数中,bp=w/bp=aq=w/bp=aq=cr=wb'_p=w/b'_p=a_q=w/b'_p=a_q=c'_r=w 的方案数(p<q<rip<q<r\le i),其中 dpi,0=1dp_{i,0}=1,则有
dpi,1=dpi1,1+dpi1,0×[bi=w]dp_{i,1}=dp_{i-1,1}+dp_{i-1,0}\times [b'_i=w]
dpi,2=dpi1,2+dpi1,1×[ai=w]dp_{i,2}=dp_{i-1,2}+dp_{i-1,1}\times [a_i=w]
dpi,3=dpi1,3+dpi1,2×[ci=w]dp_{i,3}=dp_{i-1,3}+dp_{i-1,2}\times [c'_i=w]
共有 nnww,每次修改可能导致 66ww 的答案改变,暴力做一次 DP 是 O(n)O(n) 的,所以总复杂度是 O(n2+6nm)O(n^2+6nm)
由于 dpidp_i 只依赖于 dpi1dp_{i-1},所以可以空间压缩成 dp1/2/3dp_{1/2/3},注意转移顺序。

根号分治:小于等于根号的部分

ww 进行根号分治,统计出 wwai,bi,cia_i,b'_i,c'_i 以及修改后,ww 的总出现次数 cntwcnt_w(显然 cntw=3nm\sum cnt_w=3nm)。按照 cntwcnt_w 的大小根号分治。
对于出现次数 <B<Bww,能够有效更改 dpdp 的位置不超过 BB 个,因此每次涉及到修改 ww 的操作时,暴力重做这一次 DP。
使用动态数组 vecwvec_w 存下这 BB 个位置,当进行修改操作时,相当于往 vecwvec_w 里添加或删除位置,暴力找到这个位置进行操作,时间复杂度 O(B)O(B)
接着考虑维护前缀和,令 fif_i 表示 ci=wc'_i=w 且符合题意的方案数,则 fi=dpi,2×[ci=w]f_i=dp_{i,2}\times[c'_i=w],要维护的就是 fif_i 的前缀和。
对序列进行分块,考虑到只需要进行 mm 次查询,而暴力重新做 DP 本身已经占据了 O(B)O(B) 的时间,所以需要 O(1)O(1) 修改,O(n)O(\sqrt n) 查询(这里的根号只是象征义)。令 sis_i 表示块 iiff 的和就可以做到。

根号分治:大于根号的部分

这个 DP 只有四个状态,所以考虑序列动态 DP。
[dp0dp1dp2dp3]×[1bi=w0001ai=w0001ci=w0001]=[dp0dp1dp2dp3]\begin{bmatrix} dp_0 & dp_1 & dp_2 & dp_3 \end{bmatrix} \times \begin{bmatrix} 1 & b'_i=w & 0 & 0 \\ 0 & 1 & a_i=w & 0 \\ 0 & 0 & 1 & c'_i=w \\ 0 & 0 & 0 & 1 \end{bmatrix} = \begin{bmatrix} dp'_0 & dp'_1 & dp'_2 & dp'_3 \end{bmatrix}
由于出现次数 >B>Bww 小于 n+mB\frac{n+m}{B} 个,所以单独考虑每一个 wwO(n)O(n) 维护矩阵前缀乘。
由于枚举每种 ww 已经消耗了 n\sqrt n 的时间,查询数有 mm 个,但是总修改数一定也是 mm 的级别的(和上面 O(6mn)O(6mn) 一样的道理),所以需要做到 O(1)O(1) 查询,O(n)O(\sqrt n) 修改。设 SBiSB_i 表示前 ii 个块的前缀乘,SiS_i 表示块的左端点到 ii 的前缀乘,那么查询 rr 就是 SBbelr1×SrSB_{bel_r-1}\times S_r,修改按照定义修改即可。
取矩阵中的哪个数呢?初始的 [dp0dp1dp2dp3]\begin{bmatrix}dp_0 & dp_1 & dp_2 & dp_3\end{bmatrix}[1000]\begin{bmatrix}1&0&0&0\end{bmatrix},最终希望得到 dp3dp_3,带进去算可以得到是要矩阵 (0,3)(0,3) 这个位置的数。
总时间复杂度 O((n+m)B+43×n+mB×(n+m))O((n+m)B+4^3\times \frac{n+m}{B}\times(n+m)),空间复杂度线性,BB 可以取 n+m\sqrt{n+m},但我取的 B=1000B=1000 才能通过()。

我错的一些细节

可能会出现 cntciBcnt_{c'_i}\le B,但是修改后的 cntci>Bcnt_{c'_i}>B,这样他就不会重做 cic'_i 的 DP,导致 fif_i 不能被消除贡献。

评论

1 条评论,欢迎与作者交流。

正在加载评论...