数论及其应用——同余式定理

Posted 黑大帅之家

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数论及其应用——同余式定理相关的知识,希望对你有一定的参考价值。

  这篇文章我们将介绍数论当中几个很重要的定理:威尔逊定理、费马小定理以及欧拉定理,并讨论一些基于这些定理的算法。

  首先我们给出费马小定理:如果p是素数,并且gcd(a,p) = 1 , 那么有a^(p-1) = 1(mod p)。

  而关于这个定理的证明,也是不难理解的。

  在证明之前,我们先需要知道这样两个引理。

  引理1:若a、b、c为任意3个整数,且gcd(m,c) = 1,则当ac = bc(mod m)时,有a = b (mod m)。

  引理2:设m是一个整数,且m>1,b是一个整数且gcd(m,b)=1.如果a1,a2,a3,a4,…am是模m的一个完全剩余系,那么ba[1],ba[2],ba[3],ba[4],…ba[m]也构成模m的一个完全剩余系。

  这里需要解释一下的是,所谓完全剩余系,即{a1,a2,a3,a4,…am}中任意一个元素ai % m != 0。针对引理1,通过同余式本身的特点,都十分易证,随后再基于引理1,引理2也不难得证。这里便不再累述。   有了这两个引理做铺垫,下面便可以开始费马小引理的证明了。

  构造素数p的完全剩余系P = {1,2,3,……p-1}。

  因为gcd(a,p) = 1,由引理2得素数p的新的完全剩余系:A = {a,2a,3a,……(p-1)a}。

  我们选出A、P中第i个元素,由引理1得,Ai = Pi(mod p),因此我们容易得到如下等式。

  1 * 2 * 3 *……(p-1) = a * 2a * 3a * ……(p-1)a (mod p)

  等式两边同除(p - 1)!,得到a^(p-1) = 1 (mod p),定理得证。

  既然知道了费马小定理的内容和证明了,这里我们就用它进行一下拓展利用。

  首先我们知道,在费马小定理的等式a^(p - 1) = 1 (mod p)中,如果p是素数,那么等式是成立的。

  即  isprime(p) = 1  => a^(p - 1) = 1 (mod p) 。   那么我们根据逆否命题与原命题的等价性,可以得到,a^(p - 1) != 1 (mod p) => isprime(p) = 0。

  那么逆命题和否命题与原命题是否等价呢?如果等价,我们岂不是可以通过判断是否满足费马小定理的等式来判断p是否为素数了?

  实践表明,满足费马小定理的a、p组合中,p是可以为合数的,不妨自己举几个例子。   因此对于满足费马小定理等式的a、p,有这样的定义。如果p是合数,则称p是以a为基的伪素数。

  我们不妨通过一个题目来理解一下所谓伪素数的概念。(Problem source:pku 3641)

 

Description

Fermat‘s theorem states that for any prime number p and for any integer a > 1, ap = a (mod p). That is, if we raise a to the pth power and divide by p, the remainder is a. Some (but not very many) non-prime values of p, known as base-a pseudoprimes, have this property for some a. (And some, known as Carmichael Numbers, are base-a pseudoprimes for all a.)

Given 2 < p ≤ 1000000000 and 1 < a < p, determine whether or not p is a base-a pseudoprime.

Input

Input contains several test cases followed by a line containing "0 0". Each test case consists of a line containing p and a.

Output

For each test case, output "yes" if p is a base-a pseudoprime; otherwise output "no".

  题目大意:基于伪素数的概念,给出a、p,请你判断p是否是以a为基的伪素数。

  数理分析:有了上文对伪素数概念的较少,我们知道,伪素数首先必须是合数,然后需要满足费马小定理。

  编程实现:在判断是否是伪素数的时候,由于是判断单个数字,所以使用朴素的判断法即可。而判断是否满足费马小定理的时候,则用到了我们在之前讨论过的乘法快速幂算法。   参考代码如下。

 

#include<iostream>
#include<math.h>
using namespace std;
bool ifprime(long long n)
{
     long long i;
     int iffind = 0;
     if(n == 2 || n == 1)  return 1;
     else
     {
           for(i = 2;i <= sqrt(n + 0.0);i++)
                if(n%i == 0)
           {
                 iffind = 1;
                 break;
           }
           if(iffind)
              return 0;
           else
              return 1;
     }
}

long long quick_mod(long long a , long long b , long long m) //快速幂取模,计算a^b(mod m)的值
{
     long long ans = 1;
     while(b)
     {
          if(b&1)
          {
               ans = (ans * a)%m;
               b--;
          }
          b /= 2;
          a = a * a %m;
     }
     return ans;
}

int main()
{
      long long n , a, p ,b;
      while(cin >> p >> a)
      {
            if(p == 0 && a == 0)  break;
            if(ifprime(p))
                  cout<<"no"<<endl;
            else
            {
                 long long ans = quick_mod(a,p,p);
                 if(ans == a)   cout<<"yes"<<endl;
                 else           cout<<"no"<<endl;
            }
      }
      return 0;
}

 

以上是关于数论及其应用——同余式定理的主要内容,如果未能解决你的问题,请参考以下文章

数论及其应用——欧几里得算法

数论之中国剩余定理

LightOJ1214 Large Division 基础数论+同余定理

同余定理

同余定理数论

浅谈欧拉定理及乘法逆元