CSP-S冲刺笔记(Day -24)

扩欧详解

假设我们有一个方程: a x + b y = c ax+by=c ax+by=c。这里给定了 a , b , c a,b,c a,b,c,要让我们求 ( x , y ) (x,y) (x,y)的一对整数解。保证有解

首先,为了简化问题,假设 a x + b y = 1 ax+by=1 ax+by=1。于是,我们考虑一种神奇的算法——扩展欧几里得算法

我们每次递归时,对这个式子进行如下变换:

a x + b y = 1 ax+by=1 ax+by=1
b x + ( a   m o d   b ) y = 1 bx+(a\ mod\ b)y=1 bx+(a mod b)y=1
……
1 x + 0 y = 1 1x+0y=1 1x+0y=1(此时容易解得 x = 1 , y = 0 x=1,y=0 x=1,y=0)

现在,我们考虑如何递归上传。即,我们要把 b x + ( a   m o d   b ) y = 1 bx+(a\ mod\ b)y=1 bx+(a mod b)y=1变成与 a x + b y = 1 ax+by=1 ax+by=1相同的模样。

如何变化呢?这么搞:

b x + ( a − ⌊ a b ⌋ b ) y = 1 bx+(a-\lfloor \frac a b \rfloor b)y=1 bx+(abab)y=1
b x + a y − ⌊ a b ⌋ b y = 1 bx+ay-\lfloor \frac a b \rfloor by=1 bx+aybaby=1
a y + b ( x − ⌊ a b ⌋ y ) ay+b(x-\lfloor \frac a b \rfloor y) ay+b(xbay)=1

所以,我们每次从解得的 ( x , y ) (x,y) (x,y)同时变成 y , x − ⌊ a b ⌋ y y,x-\lfloor \frac a b \rfloor y y,xbay即可。

注意,这里的 x x x是上一步的 x x x,所以我们要在把 x x x变成 y y y之前,先存储下 x x x的值。

时间复杂度 O ( l o g 1.618 m a x ( a , b ) ) O(log_{1.618}{max(a,b)}) O(log1.618max(a,b))

注意,这里的底数并不是 1.618 1.618 1.618,但是这个底数与 1.618 1.618 1.618十分接近;之所以复杂度是这个,是因为 a , b a,b a,b为斐波那契数列中相邻两项的时候是最差情况。

容易扩展到 c ≠ 1 c≠1 c=1的情况,与 g c d ( a , b ) ∣ c gcd(a,b)|c gcd(a,b)c的情况。可以发现,这个东西也可以用在逆元,甚至在复杂度允许的情况下可以代替中国剩余定理。注意如果不满足 g c d ( a , b ) ∣ c gcd(a,b)|c gcd(a,b)c,这个不等式无解

线性求逆元详解

模板

首先,请读者注意,这里的 = = =请都看成表示模的"三横杠"

我们考虑如何线性 i i i在膜 p p p意义下的逆元。

首先,假设 x x x p / i p/i p/i的商, y y y p / i p/i p/i的余数,显然有

x i + y = 0 ( m o d   p ) xi+y=0(mod\ p) xi+y=0(mod p)

等式两边同时除以 i , y i,y i,y,那么

x y − 1 + i − 1 = 0 ( m o d   p ) xy^{-1}+i^{-1}=0(mod\ p) xy1+i1=0(mod p)

i − 1 = − x y − 1 ( m o d   p ) i^{-1}=-xy^{-1}(mod\ p) i1=xy1(mod p)

i − 1 = − ⌊ p i ⌋ ( p   m o d   i ) − 1 i^{-1}=-\lfloor \frac p i \rfloor (p\ mod\ i)^{-1} i1=ip(p mod i)1

由于 p   m o d   i p\ mod\ i p mod i的逆元可以 O ( 1 ) O(1) O(1)调用(已求过),于是,我们学会了线性求逆元。

这只是一个卡常技巧,但是并不超提高组的大纲虽然从来没有考过

建议大家把这个结论背下来,考场上不用推式子了,直接用。

再书写得明确一点,假设 i n v i inv_i invi表示 i i i的逆元,那么

i n v i = ( p − ⌊ p i ⌋ ) i n v p   m o d   i inv_i=(p-\lfloor \frac p i \rfloor)inv_{p\ mod\ i} invi=(pip)invp mod i

上代码:

a[1]=1;
for (int i=2;i<=n;i++)  a[i]=((p-p/i)*a[p%i])%p;

刷题笔记

ACL B

枚举 k k k k + 1 k+1 k+1分别能被哪两个积为 n n n的数整除,然后跑几遍扩欧并取最小值即可。

时间复杂度 O ( f ( n ) l o g n ) O(f(n)logn) O(f(n)logn) f ( n ) f(n) f(n)表示 n n n的约数个数。

总结: 慎用变量名, s a v e x savex savex不能用! y 1 y1 y1不能用!!!

在这里插入图片描述
(惨

猜你喜欢

转载自blog.csdn.net/Cherrt/article/details/109035060