数学相关的一些内容。
扩展欧几里得
好久没碰数论了,感觉自己的基础挂得一塌糊涂,复习一下这玩意吧。
希望求得 ax+by=c,先同时除以 gcd 化成 ax+by=1 的形式。然后呢用欧几里得的思想,假设我们已经求得了 (b,a%b) 的答案,即已知:x0b+y0a%b=1,也就是说:
x0b+y0(a−b⌊ba⌋)=1x0b+y0a−y0b⌊ba⌋=1(x0−y0⌊ba⌋)b+y0a=1
所以答案就变成了 (y0,x0−⌊ba⌋y0)。有个结论是这样求出来的特解保证了 ∣x∣ 值最小,这就从侧面保证了 ∣x∣+∣y∣ 最小。当然我们希望的特解应该是:x0=x×gc,y0=y×gc。另外,可以求出通解如下:
{x=x0+k×gby=y0−k×ga
板子:
struct node{int x,y,g;};
inline node exgcd(int a,int b){
if(b==0)return (node){1,0,a};
node an=exgcd(b,a%b);
return (node){an.y,an.x-a/b*an.y,an.g};
}
尽管结果不会爆 int,但是在后面的运算中很有可能会用到更大的数,所以在这种题目中能开 long long 就开,总是没错的。板子。
P3518:有一个结论是说,假如 x 是密码,那么 ∀t,gcd(x,n)∣t 都应该是密码,因为它们都可以由 x 硬凑出来。设密码集合为 S,不正确的密码集合为 R,所以考虑枚举 gcdSi,令为 g,那么需要满足的是 ∀i,g∤Ri。在此基础上,由于希望可能的密码最多,那么所有 g 的倍数都应该利用上,也就是说此时的答案是 ⌊gn⌋。所以就是要求最小的 g。暴力枚举并判断是不行的,可以考虑从大到小枚举 gcd(n,m) 的因数,如果当前因数在 R 之中,那么说明这个因数的因数都是不合法的,递推地记录一下即可。有几个小的细节,一个是哈希判断的过程中可以让大于 107 以 kn 的形式存储,这样一来就不需要 map 了。然后就是找质因数的时候一定是大于一(维生素B)。