数论杂谈(欧拉定理与费马小定理结论与应用)

欧拉定理:

aφ(n)≡1 (mod n) ,其中 gcd(a,n)=1
欧拉函数是小于x的整数中与x互质的数的个数,一般用φ(x)表示。特殊的,φ(1)=1。
欧拉函数模板

// 直接求
long long Euler( long long n ){
  	 long long res = n;
	 for( long long i =2 ;i*i<=n;i++){
	 	if( n %i == 0 ){
			n/=i;
			res = res - res/i;
		}
 		while( n % i==0)
		 n/=i;
	 }
     if( n > 1 )
	     res = res - res/n;
     return res;
}

欧拉定理性质:

  1. 假设 p, q是两个互质的正整数,则 p * q 的欧拉函数为 φ(p * q) = φ§ * φ(q) , gcd(p, q) = 1 。

  2. 任意一个整数 n 都可以表示为其素因子的乘积, 那么ϕ(n) = n( 1−1/p1 )( 1−1/p2 )…( 1−1/pk ) ,

  3. 对于给定的一个素数 p , φ( p ) = p -1。则对于正整数 n = pk ,φ(n) = pk - pk-1

扩展欧拉定理:

在这里插入图片描述

当(a,m)=1时,ac≡ac mod φ(m) (mod m)
可以直接指数取模,防止指数爆炸
推广到一般情况:ab≡ab mod φ(n)+φ(n)(mod n)

费马小定理:

ap−1≡1 (mod p) ,其中 gcd(a,p)=1 ,p为质数
费马小定理是欧拉定理的一种特殊情况。
例题:
计算2^100除以13的余数
在这里插入图片描述
在这里插入图片描述

long long f(long a,long b,long n)  //定义函数,求a的b次方对n取模
{
    int t,y;
    t=1;
    y=a;
    while(b!=0)
    {
        if((b&1)==1)
        t=t*y%n;
        y=y*y%n;
        b=b>>1;
    }
    return t;
}

相关:

指数循环节

求证ab (%m)≡ab%φ(m)+φ(m)(%m),其中b≥φ(m)

费马大定理

xn + yn = zn(n >2时,没有正整数解)

逆元:

对于a和p,若 a * inv(a) % p ≡ 1,则称inv(a)为a%p的逆元。p为质数

例题

逆元与费马小定理:hdu 1576

原根

定义:

设m是正整数,a是整数,若a模m的阶等于φ(m),则称a为模m的一个原根。(φ(m)表示m的欧拉函数)
如果g是P的原根,那么gi mod P的结果两两不同,有gp-1 =1 (mod P) ,P是素数

原根存在条件

原根存在的条件有以下几个:
定理一:设p是奇素数,则模p的原根存在; [3]
定理二:设g是模p的原根,则g或者g+p是模p2的原根;
定理三:设p是奇素数,则对任意α,模pα的原根存在;
定理四:设α>=1,若g是模pα的一个原根,则g与g+pα中的奇数是模2pα的一个原根。

例题

Poj 1284 Primitive Roots

快速幂

这个就不介绍了。。。老熟人

代码

ll poww(ll a,ll b)
{
	int ans=1;
	int base=a;
	while(b){
		if(b&1)ans=ans*base%mod;
		base=base*base%mod;
		b>>=1;
	}
	return ans%mod;
}

矩阵快速幂

由快速幂延伸而来,将数延伸为矩阵,原理类似

原理:

快速幂+矩阵
矩阵乘法:左矩阵的第一行乘以右矩阵的第一列(分别相乘),乘完后相加
单位矩阵: nn的矩阵 mat ( i , i )=1; 任何一个矩阵乘以单位矩阵就是它本身 n单位矩阵=n, 可以把单位矩阵等价为整数1。(单位矩阵用在矩阵快速幂中)
在这里插入图片描述

代码:

typedef long long ll;
const int mod = 1e9 + 7;
const int MAXN = 10005;//矩阵的大小
struct Mat {
    ll m[MAXN][MAXN];
}ans, a;//ans为结果矩阵,a为输入矩阵
Mat Mul(Mat a, Mat b, int n) {//计算矩阵a乘矩阵b,n为矩阵的大小
    Mat c;//临时矩阵c
    memset(c.m, 0, sizeof(c.m));
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            for (int k = 1; k <= n; k++)
                c.m[i][j] = (c.m[i][j] + (a.m[i][k] * b.m[k][j]) % mod) % mod;
    return c;
}
Mat _power(Mat a, int b, int n) {//计算a^b,n为矩阵的大小
    for (int i = 1; i <= n; i++)//构造单位矩阵
        ans[i][i] = 1;
    while (b) {
        if (b & 1)
            ans = Mul(ans, a, n);
        a = Mul(a, a, n);
        b >>= 1;
    }
    return ans;
}       
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值