数论初步

1)欧几里得算法(辗转相除法)

代码

int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}

说明

gcd(a,b)是计算自然数a和b的最大公约数的函数,
a=bxp+q,所以gcd(b,q)既整除a又整除b,也就整除gcd(a,b)。
反之,由于q=a-bxp,同理可证gcd(a,b)既整除b又整除q,也就整除gcd(b,q)
综上所述可知gcd(a,b)=gcd(b,q)=gcd(b,a%b)
不断这样操作下去,由于gcd的第二个参数总是不断减少的,最后会得到gcd(a,b)=gcd(c,0),而0和c的最大公约数是c,所以gcd(c,0)=c
当然了,我们需要保证gcd()函数的参数中,a>b

2)唯一分解定理

一个数n肯定能被分解成若干个素数(质数)相乘的形式:n=p1a1*p2a2 …pnan
那么:

  1. 数n的因子个数:(1+a1)(1+a2)……*(1+an)
  2. 所有因子之和:(q10+q11+q12…q1a1(q20+q21+q22…q2a2…*(qn0+qn1+qn2…qnan
  3. 设两个整数的最小公倍数为lcm(a,b)
    a=p1e1p2e2…pnen
    b=p1f1p2f2…pnfn
    gcd(a,b)=p1min{e1,f1}p2min{e2,f2}…pnmin{en,fn}
    lcm(a,b)=p1max{e1,f1}p2max{e2,f2}…pnmax{en,fn}
    综上可知:lcm(a,b)*gcd(a,b)=ab

3)扩展欧几里得算法

直线上的点。求直线ax+by+c=0上有多少个整点(x,y)满足x∈[x1,x2],y∈[y1,y2]

找出一对整数(x,y)使得ax+by=gcd(a,b)

void gcd(int a,int b,int &d,int &x,int &y){
    if(!b) {
        d=a;x=1;y=0;
    }
    else{
        gcd(b,a%b,d,y,x);
        y-=x*(a/b);
    }
}

由扩展欧几里得算法可知:
1)设a,b,c为任意整数。若方程ax+by=c的一组整数解为(x0,y0),则它的任意整数解都可以写成(x0+kb,y0-ka),其中a=a/gcd(a,b),b=b/gcd(a,b),k取任意整数。
2)设a,b,c为任意整数,g=gcd(a,b),方程ax+by=g的一组解是(a0,b0),则当c是g的倍数时ax+by=c的一组解是(x0c/g,y0c/g);当c不是g的整数时无整数解。

4)同余和模运算

(a+b)mod n=((a mod n)+(b mod n)mod n)
(a-b)mod n=((a mod n)-(b mod n)+n)mod n
(a*b)mod n=(a mod n)(b mod n)mod n

5)大整数取模

问题

\quad 输入正整数n和m,输出n mod m的值。n<=10100,m<=109

分析

\quad 首先,把大整数写成“自左向右”的形式:1234=((1*10+2)*10+3)*10+4,然后用模运算公式,每步取模。

代码

int Big_Mod(char s[],int n,int m){
    int ans=0;
    for(int i=0;i<n;i++){
        ans=(int)(((long long)ans*10+s[i]-'0')%m);
    }
    return ans;
}

6)幂取模

问题

\quad 输入正整数a、b和m,输出an mod m的值。a,n,m<=109

分析

\quad 在计算xn时,我们会怎么算呢?如果只是xxx*……*x这样每个数乘起来计算n次的话,虽然算法简单,但是复杂度为O(n),往往不能满足要求。
\quad 如果n=2k,可以将其表示为xn=((x2)2)…,只要做k次平方运算就可以了。
进一步思考,

  • 当b为偶数时,ab可以转换成a2的b/2次方。
  • 当b为奇数时,ab可以转化为a2的b/2次方,再乘以a。
    像这样不断递归下去,每次n都减半,于是可以在O(log n)的时间内完成幂取模运算。

代码

int pow_mod(int a,int n,int m){
    if(n==0) return 1;
    int x=pow_mod(a,n/2,m);
    long long ans=(long long)x*x%m;
    if(n%2==1) ans=ans*a%m;
    return (int)ans;
}

7)模线性方程组

问题

\quad 输入正整数a,b,n,解方程组ax=b(mod n)。a,b,n<=109

分析

a≡b(mod n)的充要条件是:a-b是n的整数倍。
\quad 这样,原来的方程就可以理解成:ax-b是n的正整数倍。设这个“倍数”为y,则ax-b=ny,所以ax-ny=b,可以使用扩展欧几里得算法来解决这个问题。

  • 如果x是方程的解,则x≡y(mod n)的其他整数y也是方程的解。因此,当谈到同余方程的一个解时,其实指的是一个同于等价类。
  • 当 b=1时,ax≡b(mod n)的解称为a关于模n的逆,根据上面的讨论我们可知,问题转换成ax-ny=1有解,即1必须是gcd(a,n)的倍数,因此,a和n必须互质(gcd(a,n)=1)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值