数论基础(欧几里得,扩展欧几里得,逆元,斯特林)

看了点牛客网直播,整理一下。


一。欧几里得

gcd(a,b)= gcd(b,a mod b);
这个就这样吧,都知道。
证明:

a可以表示成a = kb + r,则r = a mod b

   1.假设d是a,b的一个公约数,则有a|d, b|d,而r = a - kb,因此r|d

      因此d是(b,a mod b)的公约数,证明充分性

2.假设d 是(b,a mod b)的公约数,则

           b|d , r|d ,但是a = kb +r

     因此d也是(a,b)的公约数,证明必要性

              因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等。


二。扩展欧几里得算法

这个是为了解方程:已知a, b,求x, y使a*x + b*y = gcd(a, b)。


代码实现

int exgcd(int a, int b, int &x, int &y){
  if(b == 0){
  x = 1;
  y = 0;
   return a;
  }
  int r = exgcd(b, a % b, x, y);
  int t = x;
  x = y;
  y = t - a / b * y;
   return r;
  }

解 x,y的方法的理解:

  1显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;

  也就是1*a+0*b= a

  2ax1+by1=gcd(a,b);

          在下一个exgcdbx2+(a mod b)y2=gcd(b,a mod b);

          根据欧几里德原理有gcd(a,b)=gcd(b,a mod b);

          则:ax1+by1=bx2+(a mod b)y2;

          即:ax1+by1=bx2+(a-(a/b)*b)y2=ay2+bx2-(a/b)*by2;

         根据恒等定理得:x1=y2;y1=x2-(a/b)*y2;

        这样我们就得到解 x1,y1 的方法:x1,y1 的值基于 x2,y2

例题POJ1061。


三。逆元

定义,a * x  1(mod m),则把x的最小正整数解叫做a 模 m的逆元。

三种方法求逆元:

  1、费马小定理求逆元。

  2、拓展gcd求逆元。

  3 、欧拉定理。

1.费马小定理

    a^(m-1)   1(mod m)   (m为素数)

  推到过程:

  a * a ^(m-2)  1(mod m)

  故  a^(m-2) a在模m下的逆元,(用快速幂求即可)

  但有限制条件:

  m必须为质数,且am互质。

(别问我为什么,问费马)

2。拓展欧几里得求逆元:

a*x+b*y=Gcd(a,b)

  am代入

  a*x+m*y = gcd(a,m)

  am互质,则gcd(a,m) = 1

  a*x+m*y = 1

两边模m,得 a*x  1(mod m);

x为逆元。


3.欧拉定理

故           a的逆元

        是小于m 且与 m 互质的数的个数

这样用快速幂和欧拉筛就能求了。


逆元应用

由于                 

  故     x = 1/a(mod m)

  故     (b/a)mod m

  ===>(b*x)mod m

  ===>(b%m * x%m)%m

例题hdu1576

三。斯特林公式

斯特林公式可以用来估算某数的大小,结合lg可以估算某数的位数,或者可以估算某数的阶乘是另一个数的倍数。


可以两边取对数,得:

  log10(n!) =log10(2*n*Pi)/2+n*log10(n/e)


则阶乘的位数为log10(2*n*Pi)/2+n*log10(n/e)+ 1。


感谢牛客网的学长。


你可能感兴趣的:(acm培训)