欧拉定理+费马小定理

一、欧拉定理

互质关系

如果两个整数(或者两个以上的整数)的最大公约数是1,则称他们为互质。也就是说两个整数,除了1以外,没有其它的最大公约数了,这两个整数就叫做互质关系。
比如说7,11他们的最大公约数只有1,所以他们互质;8,10他们的最大公约数为1,2,所以这两数不是互质关系。

欧拉函数

欧拉函数φ(n)是小于或等于n的正整数中与n互质的数的数目,称为欧拉函数
比如说当n=8时,与8能形成互质关系的数有4个,分别是1,3,5,7,所以φ(8)=4
具体φ(n)函数的计算公式,可以分为以下四种情况:

情况一: 当n=1,φ(1)=1

因为1与任何整数都是互质关系,所以当n=1时,φ(1)=1

情况二:当n为质数,φ(n)=n-1

因为质数与小于它的每一个数,都构成互质关系,所以当n为质数时,φ(n)=n-1 。
比如说n=3时,1,2都跟他是互质关系, n=7时,1,2,3,4,5,6都跟他是互质关系。

情况三:n = p^k (p为质数,k为指数,且大于等于1),n是质数的k次方,则φ(p^k) = p^k - p^(k-1) = p^k(1 - 1/p)

比如:φ(8) = φ(2^3) = 2^3 - 2^2 = 4
φ(27) = φ(3^3) = 3^3(1 - 1/3) = 18

情况四: n是两个互质的整数之积,如:n = p1 * p1,则 φ(n) = φ(p1p2) = φ(p1)φ(p2)

比如:φ(56)=φ(8×7)=φ(8)×φ(7)=4×6=24

同余定理

给定一个正整数n,如果两个整数a和b满足a-b能够被n整除,即(a-b)/n得到一个整数,那么就称整数a与b对n同余,记作a≡b(mod n)。这就是同余定理
例如:26≡2(mod 12), 26%12 余2, 2%12余2, 26-2/12 = 0,所以26与2对模12同余

欧拉定理


链接: https://www.jianshu.com/p/9007f61e27a8
來源:简书

二、费马小定理

费马小定理是数论中的一个定理:假如a是一个整数,p是一个质数,那么

是p的倍数,可以表示为

如果a不是p的倍数,这个定理也可以写成(同余式写法)

同余式

如果两个正整数 a和 b之差能被 n整除,那么我们就说 a和 b对模n同余,记作:

证明

任意取一个质数,比如13。考虑从1到12的一系列整数1,2,3,4,5,6,7,8,9,10,11,12,给这些数都乘上一个与13互质的数,比如3,得3,6,9,12,15,18,21,24,27,30,33,36。对于模13来说,这些数同余于3,6,9,12,2,5,8,11,1,4,7,10。这些余数实际上就是原来的1,2,3,4,5,6,7,8,9,10,11,12,只是顺序不同而已。
把1,2,3,…,12统统乘起来,乘积就是12的阶乘12!。把3,6,9,…,36也统统乘起来,并且提出公因子3,乘积就是312×12!。对于模13来说,这两个乘积都同余于1,2,3,…,12系列,尽管顺序不是一一对应,即312×12!≡12!mod 13。两边同时除以12!得312≡1 mod 13。如果用p代替13,用x代替3,就得到费马小定理xp-1≡1 mod p。

应用

  • 计算2^100除以13的余数
2^100除以13的余数
  • 证明对于任意整数a而言

    恒为2730的倍数。13减1为12,12的正因数有1, 2, 3, 4, 6, 12,分别加1,为2, 3, 4, 5, 7, 13,其中2, 3, 5, 7, 13为质数,
    根据定理,

    为2的倍数、为3的倍数、为5的倍数、为7的倍数、为13的倍数,即235713=2730的倍数。


链接: https://www.jianshu.com/p/e3df7e5d9c38
來源:简书

 
给定a,n求出 S=((((aa)a)a)a)a (mod 998244353)na。

输入:

输入仅一行. 两个正整数a和n

输出:

输出仅一行. 一个正整数


样例解释:

 ((22)2)2mod 998244353 = 256

数据范围

a,n <= 1018

 思路:

               先求出指数,即 an-1(快速幂求解),并将指数对mod-1(因为mod是质数,那么φ(mod)= mod-1),再用更新后的指数做为新的指数用快速幂求解即可。

代码如下:

复制代码
#include<cstdio>
typedef long long ll;
ll a,n;
const int M=998244353; ll mi(ll a,ll b,int mod) { ll re=1; a%=mod; while (b) { if (b&1) re=(re*a)%mod; a=(a*a)%mod; b>>=1; } return re; } int main() { scanf ("%lld%lld",&a,&n); ll t=mi(a,n-1,M-1); printf("%lld",mi(a,t,M)); return 0; } 
复制代码

课后例题://poj 3696

L,L <= 2*109. 问多少个8连在一起的数是L的倍数。如果不存在就输出0.

//这里省略输入输出规则,请读者自行注意

 

思路:

x8连在一起可以写成8*(10x-1)*9,假设d=gcd(L,8)。那么题目可以表达为:L | 8*(10x-1)*9 , 接下来我们做一些简单的式子变形:

L | 8*(10x-1)/9  ←→  L*9 | 8*(10x-1) ←→  9L/d | (10x-1) ←→  10x ≡ 1 (mod 9L/d)

引理对于任意互质的正整数a,n满足:ax≡1(mod n)最小的整数值 X0 φ(n)的约数。

证明如下:

  (反证法)假设X0不是φ(n)的约数,则φ(n)可以表示为:qX0 + r(0 <= r < X0)。题设有:aX0≡1(mod n),那么,aqX0≡1(mod n)且正整数a,n互质,所以有欧拉定理:

aφ(n)≡1(mod n),即aqX* ar≡1(mod n),继而得出:ar≡1(mod n),此时r<X0,这与X0是最小的整数值矛盾,所以假设不成立。得证。

φ(9L/d)并将其约数带入10x ≡ 1 (mod 9L/d)验证是否成立即可。求欧拉函数和快速幂,时间复杂度为:O(√(n) * log2 n)。代码如下:

复制代码
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll; ll n,mod; int Case; ll gcd(ll a,ll b) { return a%b==0 ? b : gcd(b,a%b); } ll Er(ll x) { ll re=x; for (ll i=2;i*i<=x;i++) { if (x%i==0) { re=re/i*(i-1); while (x%i==0) x/=i; } } if (x>1) re=re/x*(x-1); return re; } ll mul(ll a,ll b,ll p) { ll re=0; while (b) { if (b&1) re=(re+a)%p; a=2*a%p; b>>=1; } return re; } ll ksm(ll a,ll b,ll p) { ll re=1; a%=p; while (b) { if (b&1) re=mul(re,a,p); a=mul(a,a,p); b>>=1; } return re; } int main() { while (scanf ("%lld",&n)) { if (n==0) return 0; Case++; ll d=gcd(n,8); ll phi=Er(9*n/d); mod=9*n/d; ll flag=9223372036854775806; for (ll i=1;i*i<=phi;i++) { if (phi%i==0) { if (ksm(10,i,mod)==1) flag=min(flag,i); if (ksm(10,phi/i,mod)==1) flag=min(flag,phi/i); } } flag==9223372036854775806?printf("Case %d: 0\n",Case):printf("Case %d: %lld\n",Case,flag); } } 

猜你喜欢

转载自www.cnblogs.com/-citywall123/p/10066464.html