数学的一些小知识

枚举因子法

bool judge(int n)
{
    if(n==1) return false;
    for(int i=2;i*i<=n;i++)
    {
        if(n%i==0) return false;
        
    }
    return true;
}

 

要把1特判掉。 可以1秒内单次判断1~10^16以内的任意一个素数是否是素数

素数筛:提前处理1~N的全体素数,后可以直接判断是否是素数

const int N=1000001;
bool notprime[N];
void init()
{
    notprime[1]=1;
    for(int i=2;i

mertens定理

 

https://wenku.baidu.com/view/c167c17931b765ce05081473.html看一波,嗯,这种东西看不懂还是要看的,不求甚解

可以一秒内10^7以内的质数和合数分离开来,接下来让每个合数只删除一次

欧拉筛(线性筛)每一个素数只被记录一次,每一个合数只会被一个唯一的最小素因子标记一次。

https://wenku.baidu.com/view/4881881daaea998fcc220e99.html    原理还是可以看一下的

大致上讲:每一个数有唯一的最大因子,被唯一筛去,唯一最大因子*小于等于最小质因子就是对应的合数,且筛全了

用了反证。

const int N=1000001;
bool notprime[N];
int prime[N];
int pn;
void init()
{
    pn=0;
    notprime[1]=1;
    for(int i=2;i

 

1秒钟处理从10^7~10^8

#include里面有__gcd函数,注意要会用

最大公约数:

设两数为a、b(a>b),用

表示a,b的最大公约数,r=a (mod b) 为a除以b的余数,k为a除以b的商,即

。辗转相除法即是要证明

第一步:令

,则设

第二步:根据前提可知

第三步:根据第二步结果可知,

也是

的因数

第四步:可以断定

互质(这里用反证法进行证明:设

,则

,则

,则a与b的一个公约数

,故c非a与b的最大公约数,与前面结论矛盾,因此c也是b与r的最大公约数)从而可知

,继而

证毕

注:以上步骤的操作是建立在刚开始时

的基础之上的,即m与n亦互质。

百度上的解释,海星,不用想了。

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

 

多个数求最大公约数

int gcd(int a,int b)
{
    if(b==0) return a;
    return gcd(b,a%b);
}
int multi_gcd(int a[],int n)
{
    int res=gcd(a[0],a[1]);
    for(int i=2;i

最小公倍数略。

扩展欧几里得算法:

把这个实现和Gcd的递归实现相比,发现多了下面的x,y赋值过程,这就是扩展欧几里德算法的精髓。

可以这样思考:

对于a'=b,b'=a%b 而言,我们求得 x, y使得 a'x+b'y=Gcd(a',b')

由于b'=a%b=a-a/b*b (注:这里的/是程序设计语言中的除法)

那么可以得到:

a'x+b'y=Gcd(a',b') ===>

bx+(a - a / b * b)y = Gcd(a', b') = Gcd(a, b) ===>

ay +b(x - a / b*y) = Gcd(a, b)

因此对于a和b而言,他们的相对应的p,q分别是 y和(x-a/b*y)

使用扩展欧几里德算法解决不定方程的办法

对于不定整数方程pa+qb=c,若 c mod Gcd(a, b)=0,则该方程存在整数解,否则不存在整数解。

有种较为不严谨的方法证明,不过至少弥补了一点空白,望某些数论大师补充修改:

由于我们知道,存在一组x与y使得a*x+b*y=gcd(a,b)。

将等式两边同时乘以整数k,即a*x*k+b*y*k=gcd(a,b)*k。如果c mod gcd(a,b)=f,则0<=f

那么可以令c=gcd(a,b)*k+f。这样一来,就有a*x*k+b*y*k+f=c。

若f

0,由于f

所以f=0,即只有当c mod gcd(a,b)=0时,a*x+b*y=c有正整数解。得证。

上面已经列出找一个整数解的方法,在找到p * a+q * b = Gcd(a, b)的一组解p0,q0后,p * a+q * b = Gcd(a, b)的其他整数解满足:

p = p0 + b/Gcd(a, b) * t

q = q0 - a/Gcd(a, b) * t(其中t为任意整数)

至于pa+qb=c的整数解,只需将p * a+q * b = Gcd(a, b)的每个解乘上 c/Gcd(a, b) 即可,但是所得解并不是该方程的所有解,找其所有解的方法如下:

在找到p * a+q * b = Gcd(a, b)的一组解p0,q0后,可以

得到p * a+q * b = c的一组解p1 = p0*(c/Gcd(a,b)),q1 = q0*(c/Gcd(a,b)),p * a+q * b = c的其他整数解满足:

p = p1 + b/Gcd(a, b) * t

q = q1 - a/Gcd(a, b) * t(其中t为任意整数)

p 、q就是p * a+q * b = c的所有整数解。

上面是百度上的https://baike.baidu.com/item/扩展欧几里德算法/1053275?fr=aladdin比较透彻

int exgcd(int a,int b,int &x,int &y)
{
    if(b==0)
    {
        x=1;y=0;
        return a;
    }
    int d=exgcd(b,a%b,x,y);
    int t=x;
    x=y;
    y=t-a/b*y;
    return d;
}

线性同余方程,求逆元

int solve(int a,int b,int n)
{
    int d=gcd(a,n);
    if(b%d==0) return -1;
    int k=b/d;
    int x,y;
    exgcd(a,n,x,y);
    return x*k;
}

分解质因数

算术基本定理https://baike.baidu.com/item/算术基本定理/10920095?fr=aladdin

这个写的通俗易懂,不错。

预处理素数筛

int p[100];
int e[100];
int cnt;
int fenjie(int n)
{
    cnt=0;
    for(int i=0;i1) p[cnt]=n;
        e[cnt++]=1;
    }
}

快速幂

long long pow_mod(long long a,long long n,long long m)
{
    long long res=1;
    while(n>0)
    {
        if(n%2==1) res=res*a%m;
        a=a*a%m;
        n/=2;
    }
    return res;
}

费马小定理

模素数是有循环节的,P-1

int getphi(int n)
{
    int ans=n;
    for(int i=2;i*i<=n;i++)
    {
        if(n%i==0) 
        {
            ans-=ans/i;
            while(n%i==0)
            n/=i;
            
        }
    }
    if(n>1) ans-=ans/n;
    return ans;
}

https://baike.baidu.com/item/欧拉函数

baby step giant stephttps://www.cnblogs.com/wondove/p/7976525.html

不行了,看看其他人博客吧

你可能感兴趣的:(简单数学,入门级)