同余模定理

来源:互联网 发布:sql嵌套语句 编辑:程序博客网 时间:2024/04/29 20:27

同余模定理

定义:

•    所谓的同余,顾名思义,就是许多的数被一个数d去除,有相同的余数。d数学上的称谓为模。如a=6,b=1,d=5,则我们说a和b是模d同余的。因为他们都有相同的余数1。

•      数学上的记法为:

•      a≡ b(mod d)

•      可以看出当n<d的时候,所有的n都对d同商,比如时钟上的小时数,都小于12,所以小时数都是模12的同余.对于同余有三种说法都是等价的,分别为:

•      (1) a和b是模d同余的.

•      (2) 存在某个整数n,使得a=b+nd .

•      (3) d整除a-b.

•      可以通过换算得出上面三个说话都是正确而且是等价的.

定律:

•    同余公式也有许多我们常见的定律,比如相等律,结合律,交换律,传递律….如下面的表示:

•      1)a≡a(modd)

•      2)a≡b(modd)→b≡a(mod d)

•      3)(a≡b(modd),b≡c(mod d))→a≡c(mod d)

•      如果a≡x(modd),b≡m(mod d),则

•      4)a+b≡x+m (mod d)

•      5)a-b≡x-m(mod d)

•      6)a*b≡x*m(mod d )

•      

应用:

•    (a+b)%c=(a%c+b%c)%c;

•    (a*b)%c=(a%c*b%c)%c;

•    对于大数的求余,联想到进制转换时的方法,得到

•    举例如下,设大数 m=1234,模n

•    就等于((((1*10)%n+2%n)%n*10%n+3%n)%n*10%n+4%n)%n

大数求余的简单模板:

•    #include<stdio.h>//大数求余,其中n(除数)不是大数
char a[1000];
int main()
 int i,j,k,m,n;
{
 while(scanf("%s%d",a,&n)!=EOF)
 {
  m=0;
  for(i=0;a[i]!='\0';i++)
   m=((m*10)%n+(a[i]-'0')%n)%n;
  printf("%d\n",m);
 }
 return 0;
}

poj2635

•    题目描述:

•    给定一个大数K,K是两个大素数的乘积的值。(4<= K <= 10^100 )

•    再给定一个int内的数L (2 <=L <= 10^6 )

•    问这两个大素数中最小的一个是否小于L,如果小于则输出这个素数。

解题思路:

•    1、  Char格式读入K。把K转成千进制Kt,同时变为int型。

•    把数字往大进制转换能够加快运算效率。若用十进制则耗费很多时间,会TLE。

•    千进制的性质与十进制相似。

•    2、  高精度求模。

•    主要利用Kt数组和同余模定理。

•    例如要验证123是否被3整除,只需求模123%3

•    但当123是一个大数时,就不能直接求,只能通过同余模定理对大数“分块”间接求模

•    (a+b)%c=(a%c+b%c)%c;

•    (a*b)%c=(a%c*b%c)%c;

•    具体做法是:

•    先求1%3 = 1

•    再求(1*10+2)%3 = 0

•    再求 (0*10+3)% 3 = 1

•    那么就间接得到123%3=0,这是显然正确的

•    而且不难发现, (1*10+2)*10+3 = 123

•    这是在10进制下的做法,千进制也同理,*10改为*1000就可以了

 


0 0
原创粉丝点击