類歐幾裏得算法淺談(部分)
阿新 • • 發佈:2018-10-06
直線 過去 定義域 大於等於 畫出 一條直線 bcd abcd 取整
\(F(a,b,c,d,n)=\sum_{i=0}^n\lfloor\frac{a*i+b}{c}\rfloor\)
\(F=\sum_{i=0}{n}\sum_{j=1}{m}[\lfloor\frac{a*i+b}{c}\rfloor>=j]\)
學習類歐幾裏得算法,因為是蒟蒻,感覺網上很多都看不懂,所以自己寫一篇快活快活
第一類求和式:
\(F(a,b,c,n)=\sum_{i=0}^n\lfloor\frac{a*i+b}{c}\rfloor\)
對於這樣形式的求和,我們有以下的推導:
1.當\(a>=c\)並且\(b>=c\)時,我們有:
對於\(\lfloor\frac{a}{c}\rfloor\),
它實際等價於\(\lfloor\frac{a\mod c}{c}\rfloor+\lfloor\frac{a}{c}\rfloor\),
於是對於原先的式子,我們可以推出:
\(F(a,b,c,d,n)=\sum_{i=0}^n\lfloor\frac{a*i+b}{c}\rfloor\) =\(\sum_{i=0}^n(\lfloor\frac{a\mod c*i+b\mod c}{c}\rfloor+\lfloor\frac{a*i}{c}\rfloor+\lfloor\frac{b}{c}\rfloor)\)
進一步化為遞歸的形式就是:
\(F(a\%c,b\%c,c,n)+\frac{(n+1)n}{2}*\lfloor\frac{a}{c}\rfloor+(n+1)*\lfloor\frac{b}{c}\rfloor\)
2.當\(a<c\)或者\(b<c\)時我們有:
我們觀察可以很容易的發現,原先的和式的右邊一大堆,去掉下取整實際上表示出來就是一條直線,即:
\(F=kx+b\),(\(k=\frac{a}{c},b=\frac{b}{c})\),
然後我們就可以輕輕松松的畫出一個一次函數的圖像,在坐標系裏表現出的就是一個直角梯形,函數的定義域\(D\in[0,n]\),函數的值域\(Z\in[b,m]\),其中令\(m=\frac{a*n+b}{c}\),也就是當\(i\)等於\(n\)時的值.我們要求定義域內函數值的和,自然就是求積分,也就是這個直角梯形的面積.然後加上下整除符號,我們需要求出的就是這個梯形內整點的個數.
我們枚舉所有整點的縱坐標,就有:
\(F=\sum_{i=0}{n}\sum_{j=1}{m}[\lfloor\frac{a*i+b}{c}\rfloor>=j]\)
\(=\sum_{i=0}{n}\sum_{j=0}{m-1}[\lfloor\frac{a*i+b}{c}\rfloor>=j+1]\)
對於\([\lfloor\frac{a*i+b}{c}\rfloor>=j+1]\),我們知道,大於等於去掉下整除依舊成立,於是
\(=\sum_{i=0}^{n}\sum_{j=0}^{m-1}[(\frac{a*i+b}{c})>=j+1]\)
將分母乘過去,\(b\)移過去:
\(=\sum_{i=0}^{n}\sum_{j=0}^{m-1}[a*i>=j*c+c-b]\)
\(a\)除過去:
\(=\sum_{i=0}^{n}\sum_{j=0}^{m-1}[i>=\frac{(j*c+c-b)}{a}]\)
我們註意到,\(j\)的變化與\(i\)是無關的,於是我們可以將兩個\(\sum\)交換
\(=\sum_{j=0}^{m-1}\sum_{i=0}^{n}[i>=\frac{(j*c+c-b)}{a}]\)
\(=\sum_{j=0}^{m-1}\sum_{i=0}^{n}[i>\frac{(j*c+c-b-1)}{a}]\)
(分子減一,去掉等號)
去掉內層\(sigma\):
\(=\sum_{j=0}^{m-1} n-\frac{(j*c+c-b-1)}{a}\)
(這個顯然等價)
\(=n*m-\sum_{j=0}^{m-1} \frac{(j*c+c-b-1)}{a}\)
老規矩,轉換成遞歸形式:
\(=n*m-F(c,c-b-1,a,m-1)\)
(完)
(待補)
類歐幾裏得算法淺談(部分)