类欧几里得算法能够用 logn的时间进行如下求和
n∑i=0⌊ai+bc⌋
我们首先记
f(a,b,c,n)=n∑i=0⌊ai+bc⌋
S2(n)=∑ni=1i=n(n+1)2
S3(n)=∑ni=1i2=n(n+1)(2n+1)6
当 a≥c||b≥c时
f(a,b,c,n)=n∑i=0⌊ai+bc⌋=n∑i=0⌊(⌊ac⌋×c+a%c)i+(⌊bc⌋×c+b%c)c⌋=S2(n)×⌊ac⌋+(n+1)×⌊bc⌋+f(a%c,b%c,c,n)
当 a<c&&b<c,记 m=an+bc
f(a,b,c,n)=n∑i=0⌊ai+bc⌋=n∑i=0m∑j=1[⌊ai+bc⌋≥j]=n∑i=0m−1∑j=0[⌊ai+bc⌋≥j+1](1)=n∑i=0m−1∑j=0[ai≥jc+c−b](2)=n∑i=0m−1∑j=0[ai>jc+c−b−1](3)=n∑i=0m−1∑j=0[i>jc+c−b−1a](4)=m−1∑j=0n−⌊jc+c−b−1a⌋=nm−m−1∑j=0⌊jc+c−b−1a⌋=nm−f(c,c−b−1,a,m–1)
这里我们解释一些细节
首先由式子 (1)−>(2)为啥不能这样写?
=n∑i=0m−1∑j=0[⌊ai+bc⌋>j](1′)=n∑i=0m−1∑j=0[ai>jc−b](2′)
我们可以假象一条数轴,整除 d这个操作,相当于将这条数轴切成一段一段的,每一段的优先级是一样的,并且每一段长度都为 d,而且每个数 n的优先级就是 ⌊nd⌋,显然对于一个 n,它所在段的最小的数就是 ⌊nd⌋×d,而 (1)式到 (2)式代表的意义就是将 j映射到它在整除 d意义下,第 j段的最小值,显然只要 ⌊ai+bc⌋所在段 ≥j即对答案有贡献,是与原式子等价的
而 (1′)−>(2′)就咕咕咕了,当 j=⌊ai+bc⌋的时候,它显然对 (1′)式是没有贡献的,而如果 c不整除 ai+b的时候,ai+b>jc是显然成立的,于是它又对 (2′)式有贡献。
相似的方法,我们可以证明下面这个式子是错的
=n∑i=0m−1∑j=0[ai≥jc+c−b](3′)=n∑i=0m−1∑j=0[i≥jc+c−ba](4′)
读者可以自己证明
(tip: 若 ai和 jc+c−b在一个块里并且 jc+c−b≥ai,则 (3′)无贡献,(4′)有贡献)
(感觉这里自己理解复杂了啊?求更简单的理解方法 qwq)
然后你跑一遍递归就能求出来原式子了。
于是基础的类欧几里得算法就讲完了?
但是我们会止步于此吗?
(大雾)
咕咕咕,所以我们的模板还是没讲完 qwq
来我们把剩下两条式子也推一推
记
g(a,b,c,n)=∑ni=0i⌊ai+bc⌋
h(a,b,c,n)=∑ni=0⌊ai+bc⌋2
其实手法是相似的呢,我们先求一遍 g(a,b,c,n)
当 a≥c||b≥c
g(a,b,c,n)=n∑i=0i⌊ai+bc⌋=S3(n)×⌊ac⌋+S2(n)×⌊bc⌋+g(a%c,b%c,c,n)
当 a<c&&b<c,记 m=an+bc
g(a,b,c,n)=n∑i=0⌊ai+bc⌋=n∑i=0m−1∑j=0i[i>⌊jc+c−b−1a⌋]=m−1∑j=012(n+⌊jc+c−b−1a⌋+1)(n–⌊jc+c−b−1a⌋])=12m−1∑j=0n2−⌊jc+c−b−1a⌋2+n–⌊jc+c−b−1a⌋=12(n2m−h(c,c−b−1,a,m−1)+nm−f(c,c−b−1,a,m−1))=12[nm(n+1)−h(c,c−b−1,a,m−1)−f(c,c−b−1,a,m−1)]
你会震惊地发现,这个 g(a,b,c,n)竟然还和 h有关系,不过不用惊讶,我们等等推完 h你就知道怎么处理了
现在我们来求 h(a,b,c,n)
当 a≥c||b≥c
h(a,b,c,n)=n∑i=0⌊ai+bc⌋2=n∑i=0⌊(⌊ac⌋×c+a%c)i+(⌊bc⌋×c+b%c)c⌋2=n∑i=0(⌊ac⌋i+⌊bc⌋+⌊(a%c)i+(b%c)c⌋)2=n∑i=0⌊ac⌋2i2+⌊bc⌋2+⌊(a%c)i+(b%c)c⌋2+2(⌊ac⌋⌊bc⌋i+⌊ac⌋⌊(a%c)i+(b%c)c⌋i+⌊bc⌋⌊(a%c)i+(b%c)c⌋)=S3(n)⌊ac⌋2+(n+1)⌊bc⌋2+h(a%c,b%c,c,n)+2S2(n)⌊ac⌋⌊bc⌋+2g(a%c,b%c,c,n)⌊ac⌋+2f(a%c,b%c,c,n)⌊bc⌋
当 a<c&&b<c,记 m=an+bc
h(a,b,c,n)=n∑i=0⌊ai+bc⌋2
等等,如果用相同的手法的话,我们不应该令 m=(an+bc)喵?但是酱紫做的话你会发现递归就不能保证 m≤n了,然后你就咕咕咕了。
我们可以采用求和降次的手法 (就是 n次多项式的 n项求和为 n+1次,我们只需要多一次枚举就能降次)
在这题我们用的是
(2n∑i=1i)–n=n2
代入有
h(a,b,c,n)=n∑i=0⌊ai+bc⌋2=n∑i=0(2m∑j=1j)−⌊ai+bc⌋=n∑i=0(2m−1∑j=0j+1)−⌊ai+bc⌋=2m−1∑j=0(j+1)n∑i=0[⌊ai+bc⌋≥j+1]−n∑i=0⌊ai+bc⌋=2m−1∑j=0(j+1)n∑i=0[ai≥jc+c−b]−f(a,b,c,n)=2m−1∑j=0(j+1)n∑i=0[i> ⌊jc+c−b−1a⌋]−f(a,b,c,n)=2m−1∑j=0(j+1)(n−⌊jc+c−b−1a⌋)−f(a,b,c,n)=2m−1∑j=0nj+n−j⌊jc+c−b−1a⌋−⌊jc+c−b−1a⌋−f(a,b,c,n)=2nS2(m−1)+2nm−2g(c,c−b−1,a,m−1)−2f(c,c−b−1,a,m−1)−f(a,b,c,n)=2nS2(m)−2g(c,c−b−1,a,m−1)−2f(c,c−b−1,a,m−1)−f(a,b,c,n)
然后我们的式子就推完了,在实现方面,因为 g和 h都有互相推导的关系,所以我们可以存一个结构体,在结构体里把三个函数算出来然后递归做
具体实现看代码吧 qwq
由于这篇 blog 的公式太多了,如果有错的话请在评论处指出谢谢 qwq
2 条评论
Remmina · 2019年1月29日 1:34 下午
佩服 qhy 啊,能用这破 MarkDown 编辑器里写这么长的公式 QwQ
quhengyi11 · 2019年1月29日 1:51 下午
我在 moeditor 里面编辑然后复制过来的 qwq