专栏文章

题解:AT_agc057_f [AGC057F] Reflection

AT_agc057_f题解参与者 1已保存评论 0

文章操作

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

当前评论
0 条
当前快照
1 份
快照标识符
@min3wf3z
此快照首次捕获于
2025/12/01 20:09
3 个月前
此快照最后确认于
2025/12/01 20:09
3 个月前
查看原文

前言

一道挺有意思的计数题,自己看洛谷题解不是很懂,max 讲了然后自己去看 AT 的题解就很易懂了。是好题,值得做!
然后就是你可能需要有一定耐心才能看得懂,但是这篇题解会尽可能详细地讲这道题。
upd on 2025.11.21 8:00:感谢 max 发现的一处微小错误。

题解

首先我们可以换一种三元组的表达方式,考虑记录 (x,a,b)(x,a,b) 表示中间的点是 xx,其两边分别间隔 a,ba,b。考虑变化的过程,若钦定 a<ba<b 那么有 (x,a,b)(x+a,a,ba)(x,a,b)\to(x+a,a,b-a)(x,a,b)(xa,ba,a)(x,a,b)\to(x-a,b-a,a)。我们考虑换一种更简洁清晰的表达方式,这里我使用了 AT 的图片:
这里我们省略了 xx 仅保留 (a,b)(a,b),然后将两种转化看成两条边,边权就是 xx 的变化量。于是我们统计不同的 (x,a,b)(x,a,b) 就变成了统计从根到图上每个点的路径数,可以发现两者恰好构成双射。进一步思考,一条边上有边权,那么对于一条从根开始的路径一定对应一个边权和。那么要统计到一个点的不同路径数,就相当于是统计边权和的情况数。计数的时候需要考虑不重不漏,所以我们需要找到一种合理的统计方式,在此之前我们可以先寻找图的性质。
我们设 aia_i 表示第 ii 次变化时中间的点的移动距离,也就是 aia_i 代表第 ii 列的边的边权的绝对值。考虑这个序列一种生成方式是在做辗转相减法的过程中记录较小的数,所以可以从这方面入手寻找性质。注意到在辗转相减的过程中我们会在某段时间减去相同的值,于是考虑把 aia_i 划分成 O(logV)\mathcal O(\log V) 个段。假设共有 mm 段,对于第 ii 段,我们假设有 cic_ibib_i,现在我们在 bib_i 上考虑。
这里有一个非常重要并且巧妙的性质:bi=ci+1×bi+1+bi+2(im2)b_i=c_{i+1}\times b_{i+1}+b_{i+2}(i\le m-2),就比如上图中有 7=2×3+17=2\times3+1。等式成立的原因可以考虑用辗转相除法优化辗转相减法的时候,有 (a,b)(b,amodb)(a,b)\to (b,a\bmod b),这其实就是一个被除数 == 除数 ×\times++ 余数的等式。注意这个性质在最后其实并不成立,因为最后一段的 1 全选就能凑出上一段的数,于是我们考虑手动去掉一个 1 保持性质。有了这个重要的性质之后现在考虑计数,我们先翻译一下这个结论,把它变成能够直接用的:选择了一个 bib_i 等价于选择了整段的 bi+1b_{i+1} 以及一个 bi+2b_{i+2}
那么我们考虑将所有的后者换成前者。当后者不能换成前者的时候说明第 ii 段已经全选了,以此类推,前 ii 段也已经全选了。说明我们一种边权和可以看成这样一种选择方案:选择了一个前缀 ii 满足第一段一直到第 ii 的所有数都已经全选,后面还有若干的 bjb_j 被选择,但是如果选择了整段的 bjb_j 就不能选择 bj+1b_{j+1}
刻画出了选择方式我们就可以对此 dp 了。设 fi,0/1f_{i,0/1} 表示考虑到了第 ii 段,在前缀全选的段不足 ii 的情况下这个段是否全选。转移是简单的,但这里还是负责任地讲一下。对于 fi,0f_{i,0},考虑这一段从哪个状态转移,并且这一段选多少个数。于是有 fi,0=fi1,1+ci×(fi1,0+1)f_{i,0}=f_{i-1,1}+c_i\times(f_{i-1,0}+1)。考虑如果上一段全选那么这一段不能选数;如果上一段不是全选那这一段可以选 [0,ci1][0,c_i-1] 个数;如果全选的前缀是 ii 那么这一段能选 [0,ci1][0,c_i-1] 个数。对于 fi,1f_{i,1}fi,1=fi1,0f_{i,1}=f_{i-1,0},这是显然的。
最后我们考虑统计答案。对于一段的贡献一起统计,设 sis_i 表示第 ii 段的答案。考虑一个段 ii 最后一个位置 jj 的答案为 fj,0+fj,1+1f_{j,0}+f_{j,1}+1,但是一个段中不同的位置其 fj,0f_{j,0} 是不同的,因为 fj,0f_{j,0} 与这个段的前缀长度有关。什么意思呢?就是说假设位置 jj 是第 ii 段的第 kk 个位置,我们转移 fj,0f_{j,0} 的时候这个段能够选择的数其实只有 [0,k1][0,k-1],所以一个段中的 fj,0f_{j,0} 略有不同,于是统计一个段的答案的时候就不能直接写 ci×(fi,0+fi,1+1)c_i\times(f_{i,0}+f_{i,1}+1),而是去枚举段中的每个数,有:
si=j=1ci(fi1,1+j×(fi1,0+1))+fi1,0+1s_i=\sum_{j=1}^{c_{i}}(f_{i-1,1}+j\times(f_{i-1,0}+1))+f_{i-1,0}+1
jj 提出来化简即可。考虑最后的答案之和,根据上图,注意到除了最后一个段其他都有两个点,然后你还要考虑不做任何操作以及开头还有两个选择,并且前面去掉的那个 1 最后还会有贡献需要加回去,于是答案为 3+(i=1m2si)2sm2sm13+\left(\sum_{i=1}^{m}2s_i\right)-2s_{m-2}-s_{m-1}。最后时间复杂度为 O(qlog(ca)\mathcal O(q\log (c-a))。

评论

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

正在加载评论...