欧几里得(辗转相除)算法
最大公因数gcd求法(辗转相除法)
易得:\(\gcd(a, b) = \gcd(a − b, b)\)。
多减几次得:\(gcd(a, b) = gcd(a \% b, b)\)
对于边界 \(a = 0\),此时的 \(b\) 即是最大公约数。
int gcd(int a, int b) {
return !b ? a : gcd(b, a%b);
}
exgcd(拓展欧几里得算法)
此算法可用于解不定方程和求非质数意义下的逆元):
方程:ax + by = c (a,b,c均为整数,求x,y的整数解)
核心思路:在求gcd的末状态求出\(x_末,y_末\),又因为有个天才脑洞大开发现可以顺着gcd递归回去,于是可以求出一组x,y的特解,再找通解的表达。
具体做法:
当c 不是 gcd(a,b) 的倍数,时无x,y整数解。(裴蜀定理)
否则:ax + by = k * gcd,可先求出x/k,y/k
gcd末状态:
a = gcd, b = 0。此时\(x_末 = 1, y_末随机取\)
gcd的转移方法是:ax + by = gcd = bx' + (a - \({\lfloor a / b \rfloor}\) * b)*y';(gcd的递归转移)
整理一下:y = x' - \({\lfloor a / b \rfloor}\) * y', x = y'
递归回去可得一组x/k,y/k的整数解, 再乘上k就是一组x,y的特解
接下来就是求通解:
先令有解{x1,y1}{x2,y2}
\(ax_1 + by_1 = c\)
\(ax_2 + by_2 = c\)
\(∴a(x_1 - x_2) = b(y_2 - y_1)\)
\(两边同除gcd(a,b),得a'(x_1 - x_2) = b'(y_2 - y_1),此时a'与b'互质\)
\(∴(x_1 - x_2) = k * b', (y_2 - y_1) = k * a'\)
整理一下:\(x_1 = k * b' + x_2,y_1 = y_2 - k * a'(k为任意,
x_2,y_2为特解,x_1,y_1为通解)\)
代码:
void exgcd(long long a, long long b){
if(b == 0) {
x = 1, y = 0;
gcd = a;
return ;
}
exgcd(b, a % b);
tmp = x, x = y, y = tmp - (a/b) * y;
}
用 \(exgcd\) 求逆元:\(ax = 1 (\bmod p) => ax = 1 + pk => ax - pk = 1\),然后解不定方程。
类欧几里得算法
给定 \(n, a, b, c\) ,分别求
\[\sum_{i=0}^{n}\left\lfloor \frac{ai+b}{c} \right\rfloor\,,\ \sum_{i=0}^{n}{\left\lfloor \frac{ai+b}{c} \right\rfloor}^2\,,\ \sum_{i=0}^{n}i\left\lfloor \frac{ai+b}{c} \right\rfloor
\]
先求第一个,后面两个的思路类似于第一个。为了方便,我们定义:
\[f(a,b,c,n)=\sum_{i=0}^{n}\left\lfloor \frac{ai+b}{c} \right\rfloor\
\]
整体思路:如果 \(a>c\) 或 \(b>c\),把 \(f(a,b,c,n)\) 转换成 \(f(a\bmod c,b\bmod c,c,n)\),否则转化成类似于 \(f(c,c-b-1,a,m)\) 的形式。
具体做法:
对于 \(a\ge c\) 或 \(b\ge c\) 时:
\[\begin{aligned}
f(a,b,c,n)&=\sum_{i=0}^n\left\lfloor \frac{ai+b}{c} \right\rfloor\\
&=\sum_{i=0}^n\left\lfloor
\frac{\left(\left\lfloor\frac{a}{c}\right\rfloor c+a\bmod c\right)i+\left(\left\lfloor\frac{b}{c}\right\rfloor c+b\bmod c\right)}{c}\right\rfloor\text{这一步是关键}\\
&=\frac{n(n+1)}{2}\left\lfloor\frac{a}{c}\right\rfloor+(n+1)\left\lfloor\frac{b}{c}\right\rfloor+
\sum_{i=0}^n\left\lfloor\frac{\left(a\bmod c\right)i+\left(b\bmod c\right)}{c}
\right\rfloor\\
&=\frac{n(n+1)}{2}\left\lfloor\frac{a}{c}\right\rfloor
+(n+1)\left\lfloor\frac{b}{c}\right\rfloor+f(a\bmod c,b\bmod c,c,n)
\end{aligned}
\]
对于 \(a,b < c\),
\[\begin{aligned}
f(a,b,c,n) &= \sum^n_{i=0}\sum^{\left\lfloor \frac{ai+b}{c} \right\rfloor-1}_{j=0} 1\\
&=\sum^{\left\lfloor \frac{an+b}{c} \right\rfloor-1}_{j=0}\sum^n_{i=0}[j \le \left\lfloor \frac{ai+b}{c} \right\rfloor - 1]
\end{aligned}
\]
转化右边的式子:
\[\begin{aligned}
j\le\left\lfloor \frac{ai+b}{c} \right\rfloor -1
&\iff j+1\leq \left\lfloor \frac{ai+b}{c} \right\rfloor
\iff j+1\leq \frac{ai+b}{c}\\
&\iff jc+c\le ai+b \iff jc+c-b-1< ai\\
&\iff \left\lfloor\frac{jc+c-b-1}{a}\right\rfloor< i
\end{aligned}
\]
为了方便表示,令 \(m=\left\lfloor \frac{an+b}{c} \right\rfloor\),则
\[\begin{aligned}f(a,b,c,n)&=\sum_{j=0}^{m-1}\sum_{i=0}^n\left[i>\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor \right]\\&=\sum_{j=0}^{m-1}(n-\left\lfloor\frac{jc+c-b-1}{a}\right\rfloor)\\&=nm-f\left(c,c-b-1,a,m-1\right)\end{aligned}
\]
递归即可。\(O(n\log n)\)
对于
\[g(a,b,c,n) = \sum_{i=0}^{n}i{\left\lfloor \frac{ai+b}{c} \right\rfloor}\\
h(a,b,c,n) = \sum_{i=0}^{n}{\left\lfloor \frac{ai+b}{c} \right\rfloor}^2
\]
同样的做法,可以得到:
对于 $ a\ge c$ 或 \(b\ge c\)
\[g(a,b,c,n)
=g(a\bmod c,b\bmod c,c,n)+\left\lfloor\frac{a}{c}\right\rfloor\frac{n(n+1)(2n+1)}{6}+\left\lfloor\frac{b}{c}\right\rfloor\frac{n(n+1)}{2}\\
\]
\[\begin{aligned}
h(a,b,c,n)
&=\frac{n(n+1)(2n+1)}{6}\left\lfloor\dfrac{a}{c}\right\rfloor^2+(n+1)\left\lfloor\frac{b}{c}\right\rfloor^2+n(n+1)\left\lfloor\dfrac{a}{c}\right\rfloor\left\lfloor\frac{b}{c}\right\rfloor\\
&\ \ \ \ +2\left\lfloor\dfrac{a}{c}\right\rfloor g(a\bmod c,b\bmod c,c,n)+2\left\lfloor\dfrac{b}{c}\right\rfloor f(a\bmod c,b\bmod c,c,n)\\
&\ \ \ \ +h(a\bmod c,b\bmod c,c,n)
\end{aligned}
\]
否则:
\[g(a,b,c,n) = \frac{1}{2}[mn(n+1)-h(c,c-b-1,a,m-1)-f(c,c-b-1,a,m-1)]\\
h(a,b,c,n) = m(m+1)n-2f(c,c-b-1,a,m-1)-2g(c,c-b-1,a,m-1)-f(a,b,c,n)
\]
其中 \(m=\left\lfloor \frac{an+b}{c} \right\rfloor\).
吐槽一下:这玩意写起来是真史,要是不给我公式要我手推出来写代码,不知道得调到什么时候。