类欧几里得算法推导

类欧几里得算法推导

一般形式:\(f(a,b,c,n)=∑{_{i=0}^{n}}⌊(ai+b)/c⌋\)

设:\(a=x_1c+y_1,b=x_2c+y_2\)
那么

\(⌊(ai+b)/c⌋\)

\(=⌊((x_1c+y_1)i+(x_2c+y_2))/c⌋\)

\(=⌊(y_1i+y_2)/c⌋+x_1*i+x_2⌋\)

\(=⌊(y_1i+y_2)/c⌋+x_1*i+x_2\)

那么原式就有:

\(f(a,b,c,n)\)

\(=∑{_{i=0}^{n}}⌊(ai+b)/c⌋\)

\(=∑{_{i=0}^{n}}(⌊(y_1i+y_2)/c⌋+x_1*i+x_2)\)

\(=∑{_{i=0}^{n}}⌊(y_1i+y_2)/c⌋+∑{_{i=0}^{n}}x_1*i+∑{_{i=0}^{n}}x_2\)

\(=∑{_{i=0}^{n}}⌊((y_1i+y_2))/c⌋+x_1*(n+1)*n/2+x_2*(n+1)\)

那么就转为求\(∑{_{i=0}^{n}}⌊((y_1i+y_2))/c⌋\)的值。

其实很容易发现:\(∑{_{i=0}^{n}}⌊(y_1i+y_2)/c⌋\)和最初的式子\(∑{_{i=0}^{n}}⌊(ai+b)/c⌋\)是一个样子,那么为什么要进行这一步转换呢?

\(a=x_1c+y_1,b=x_2c+y_2\)可知,\(y_1<=a,y_2<=b\),进一步可知\(y_1*i+y2<=a*i+b\),所以\(⌊(y_1i+y_2)/c⌋<=⌊(ai+b)/c⌋\)

\(up1=⌊(y_1n+y_2)/c⌋,up2=⌊(an+b)/c⌋\)\(up\)代表取值上界。

\(a,b>c\)时,\(up2\)\(up1\)的转换可以大大缩小取值上界。
缩小取值上界的作用将在后文进行讲解。

假设:\(f(i)=(y_1i+y_2)/c\)的图像如下

那么加上下取整之后的图像为:

首先从几何角度来讲,一个点\((a,b)\)的下取整表示在\(x=a\)这条线上满足\(y>0,y<=b,\)\(y\)是整数的点的个数。

那么就可以通过枚举\(x\)或者\(y\)得到所有绿色横线上的值,那么就有新的问题了,即哪种枚举时间复杂度最优。

\(n-up1\)

\(>=n-((y_1*n+y_2)/c)\)

\(=1/c(nc-y_1n-y_2)\)

\(=1/c(n(c-y1)-y2)\)

由于\(c-y1>0\)且大多题目有\(n>>c>y_2\),所以本式最终结果大于0,即得证\(n>up1\)枚举\(y\)坐标的次数一定小于枚举\(x\)坐标的次数。

利用容斥可以得到一种算法。

对于每个\(y\)\(f(i)<y\)的个数,然后用\(n*m\)减去这部分。

如果枚举合法状态的话,下界为\(⌊y_2/c⌋=0\),所以枚举\(y\)一定是从\(0\)枚举到\(up1\)\()\)

那么一定不存在\(f(i)<y\)的点,那么就从\(1\)枚举到\(up1\)

\((ai+b)/c<y\)移项得到\(i<(cy-b)/a\)\(i\)取整数,\((cy-b-1)/a\)可以保证当\((cy-b)/a\)为整数的时候,经过这个转换,再下取整,可以得到一个合法边界。

所以\(sum=n*up-∑{_{y=1}^{up}}(cy-b-1)/a=n*up-∑{_{y=0}^{up-1}(cy+c-b-1)/a}\)

\(∑{_{y=0}^{up-1}(cy+c-b-1)/a}=f(c,c-b+1,a,up-1)\)

前面的mod处理也是为了这里下放的\(c-b+1>0\)

所以就得到整体的递推式:

ll calc(ll a, ll b, ll c, ll n) 
{
    if (!a) return b / c * (n + 1);
    if (a < c && b < c)
    {
        ll m = (a * n + b) / c;
        if (!m) return 0;
        return n * m - calc(c, c - b - 1, a, m - 1);
    }
    return calc(a % c, b % c, c, n) + n * (n + 1)/2 * (a / c) + (n + 1) * (b / c);
}
posted @ 2020-10-24 09:10  林生。  阅读(115)  评论(0)    收藏  举报