数论09.10.08

只是一个知识体系
目录:
1整除及其性质
2常见定理
3模与余
4重要定理
5素数及其相关定理
6莫比乌斯相关
7逆序数
8原根
9离散对数


1.若a|b <-> -a|b <-> a|-b <-> |a| | |b|
2.若a|b,b|c -> a|c
3.若a|b,a|c -> a|(bx+cy) 其中x,y为任意整数
4.若a|b -> am|bm 其中m为非零整数
5.若a|b,b|a -> b=±a <-> |b|=|a|
6.若a|bc,且a与c互质,则a|b
7.若a|b,a|c,且b与c互质,则a|bc
8.若a|b,c为任意整数,则b|ac
9.对任意整数a,b>0,存在唯一的数对q,r,使a=bq+r,其中0≤r<b,这个事实称为带余除法定理,是整除理论的基础
10.若c|a,c|b,则称c是a,b的公因数。若d是a,b的公因数,d≥0,且d可被a,b的任意公因数整除,则d是a,b的最大公因数。若a,b的最大公因数等于1,则称a,b互素,也称互质。累次利用带余除法可以求出a,b的最大公因数,这种方法常称为辗转相除法。又称欧几里得算法。

1.欧拉定理:对于互质的正整数a和n,有a^φ(n) ≡ 1(mod n)
2.费马小定理:若gcd(a,b)=1,则a^(p-1) ≡ 1 (mod n)
3.威尔逊定理:当且仅当p为素数时,(p-1)! ≡ -1 (mod p)(阶乘呈爆炸性增长 实际操作意义不大)
4.卢卡斯(Lucas)定理

设 P 为素数,a,b∈N∗,并且
a=akpk+ak−1pk−1+⋯+a1p+a0
b=bkpk+bk−1pk−1+⋯+b1p+b0

这里 0≤ai,bi≤p−1 都是整数,i=0,1,2,⋯,k. 则有
Cba≡Cbkak∗Cbk−1ak−1∗⋯∗Cb0a0(mod P)

用于计算组合数取模,其中p必须是素数

1.模运算:

1.取模运算:a % p(a mod p),表示a除以p的余数。
2.模p加法:(a + b) % p = (a%p + b%p) % p
3.模p减法:(a - b) % p = (a%p - b%p) % p
4.模p乘法:(a * b) % p = ((a % p)*(b % p)) % p
5.幂模p : (a^b) % p = ((a % p)^b) % p
6.模运算满足结合律、交换律和分配律。
7.a≡b (mod n) 表示a和b模n同余,即a和b除以n的余数相等。
2.同余的性质:

1.反身性:a≡a (mod m);
2.对称性:若a≡b(mod m),则b≡a (mod m);
3.传递性:若a≡b(mod m),b≡c(mod m),则a≡c(mod m);
4.同余式相加:若a≡b(mod m),c≡d(mod m),则a c≡b d(mod m);
5.同余式相乘:若a≡b(mod m),c≡d(mod m),则ac≡bd(mod m)。


1快速幂:快速幂就是快速算底数的n次幂

LL pow(LL a, LL n, LL p)    //快速幂 a^n % p
{
    LL ans = 1;
    while(n)
    {
        if(n & 1) ans = ans * a % p;          //若不取模就去掉p
        a = a * a % p;
        n >>= 1;
    }
    return ans;
}

2大数快速幂(>longlong)

#include <bits/stdc++.h>

using namespace std;
const int mod=1e9+7;
long long quick_mod(long long a,long long b)
{
    long long ans=1;
    while(b){
        if(b&1){
            ans=(ans*a)%mod;
            b--;
        }
        b/=2;
        a=a*a%mod;
    }
    return ans;
}//内部也用快速幂
long long quickmod(long long a,char *b,int len)
{
    long long ans=1;
    while(len>0){
        if(b[len-1]!='0'){
            int s=b[len-1]-'0';
            ans=ans*quick_mod(a,s)%mod;
        }
        a=quick_mod(a,10)%mod;
        len--;
    }
    return ans;
}

int main(){
    char s[100050];
    int a;
    while(~scanf("%d",&a))         //求a^s%mod
    {
        scanf("%s",s);
        int len=strlen(s);
        printf("%I64d\n",quickmod(a,s,len));
    }
    return 0;
}


四.数论重要定理及应用
1.欧几里得定理
1.1定义:

gcd(a,b)=gcd(b,a%b)

1.2最大公约数与最小公倍数

int gcd(int a,int b)   //最大公约数
{
    if(b==0)  return a;
    else return gcd(b,a%b);
}

         
int lcm(int a,int b)  //最小公倍数
{
    return a/gcd(a,b)*b;    //防止溢出
}

2.扩展欧几里得
2.1定义:

ax+by=gcd(a,b)=d,在已知a,b的情况下
求解出一组x,y
2.2推导过程:

因为a%b=a-(a/b)b
则有 d=bx1+[a-(a/b)b]y1=bx1+ay1-(a/b)by1=ay1+b(x1-a/by1)
故 x=y1,y=x1-a/by1
2.3性质:

1.若通过扩展欧几里得求出一组特解(x0,y0),那么有ax0+by0=d.
则方程的通解为,其中k为任意整数
x=x0+k*(b/d)
y=y0-k*(a/d)
2.已知ax+by=d的解,对于ax+by=c的解,c为任意正整数,只有当d|c时才有解
其通解为
x=(c/d)x0+k(b/d)
y=(c/d)y0-k(a/d)
2.4常见用法:

(1)求形如ax+by=c的通解,或从中选取某些特解
(2)求乘法逆元
(3)求解线性同余方程

int exgcd(int a, int b, int &x, int &y) {         //x,y初始为任意值,最后变为一组特解
    if(b == 0) {        //对应最终情况,a=gcd(a,b),b=0,此时x=1,y为任意数
        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;     //gcd(a,b)
}

3.线性同余方程(模线性方程)
3.1定义:

形如:ax≡b (mod n)的方程。
3.2性质

定理1:此方程对于未知量x有解当且仅当 gcd(a,n) | b
定理2:d=gcd(a,n),若d|b,则方程恰好有d个模n不同余的解,否则方程无解
定理3:若x0是方程的任一解,则该方程对模n有d个不同的解,分别为xi=x0+k*(b/d),(k=1,2,…,d-1)
3.3解线性同余方程:

ax≡b (mod n) —> ax+ny=b d=gcd(a,n),若不满足d|b,则方程无解 否则, ax0+ny0=d,利用扩展欧几里得求出一组特解(x0,y0) 然后,x=x0*(b/d)%n就是原方程的一个解 且其有d个不同的解,为xi=(x+k*(b/d))%n,0<=k< d
3.3.1最小整数解:

由于一元线性同余方程的通解可以写成res = ( X + i * (b /d) ) (mod n) = X + i * (n/d) + n * y,由于 y 与 i 均为变量因此可以将其合并得到式子 res = X + y * ( n/d) (其中将原式中的 n * y 看做 n/d * d * y,由于y是变量因此可以将 d*y这个整体看为 y),因此可以得到res = X(mod n/d) ,设m/d 为 t ,其最小正整数解可表示为 (X%t + t) % t。

void RemainderEquation(int a,int b,int n)
{
    int X,Y,d;
    long long res;
    long long min_res;
    d=gcd(a,n);
    exgcd(a,n,X,Y);
    if(b%d == 0)
    {
        X = X * (b / d) % n;//得到同于方程一解
        for(int i = 0 ; i < d; i++)
        {
            res = (X + (i * (b/d))) % n;
            printf("%lld\n",res);             //输出所以解
        }
        min_res=(X%(n/d)+(n/d))%(n/d);    
        cout<<min_res<<endl;       //输出最小解
    }else
    {
        printf("No Sulutions!\n");
    }
}

4.中国剩余定理(模线性方程组)
4.1定义:

对于模线性方程组
这里写图片描述
这里写图片描述
4.2常规中国剩余定理:各m互质时

int CRT(int a[], int m[], int n) {
    int M = 1;
    int ans = 0;
    for(int i = 1; i <= n; i++) {
        M *= m[i];
    }
    for(int i = 1; i <= n; i++) {
        int x, y;
        int Mi = M / m[i];
        exgcd(Mi, m[i], x, y);
        ans = (ans + Mi * x * a[i]) % M;
    }
    if(ans < 0) ans += M;
    return ans;
}

4.3扩展中国剩余定理:各m不互质

#include<iostream>
#include<cstdio>
#include<climits>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
const int maxn=1e5+5;
int n;
LL exgcd(LL a,LL b,LL &x,LL &y){
    if(!b){x=1,y=0;return a;}
    LL re=exgcd(b,a%b,x,y),tmp=x;
    x=y,y=tmp-(a/b)*y;
    return re;
}
LL m[maxn],a[maxn];      //m为模数集,a为余数集
LL exCRT(){
    LL M=m[1],A=a[1],t,d,x,y;int i;
    for(i=2;i<=n;i++){
        d=exgcd(M,m[i],x,y);//解方程
        if((a[i]-A)%d)return -1;//无解
        x*=(a[i]-A)/d,t=m[i]/d,x=(x%t+t)%t;//求x
        A=M*x+A,M=M/d*m[i],A%=M;//日常膜一膜(划掉)模一模,防止爆
    }
    A=(A%M+M)%M;
    return A;
}
int main()
{
    int i,j;
    while(scanf("%d",&n)!=EOF){
        for(i=1;i<=n;i++)scanf("%lld%lld",&m[i],&a[i]);
        printf("%lld\n",exCRT());
    }
    return 0;
}

原文链接:https://blog.csdn.net/weixin_43093481/article/details/82229718

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值