zoukankan      html  css  js  c++  java
  • 简单数学


    突然发现之前也写过一篇文章叫“简单数学”,缘,妙不可言


    博主整理了一下(OI)中简单的数论知识,故取名简单数学,以后会随着学习的深入慢慢扩展开来。

    以下的代码部分没经过验证,可能一定会出锅

    质数

    质数的判定

    顾名思义就是判定某一个数是不是质数

    试除法

    一个结论:

    若一个正整数(N)为合数,那么一定存在一个正整数(T)能够整除(N),且(2le N le sqrt N)

    该结论可以通过反证法证明,这里不再赘述(直接背过他不香吗?)

    bool judge_prime(int N){
        for(int i=2;i*i<=N;++i)
            if(N%i==0) return 0;
        return 1;
    }
    

    容易看出复杂度为(O( sqrt N))

    质数的筛选

    顾名思义就是晒出出(1acksim N)中的质数

    Eratosthenes筛法

    核心思想就是质数的倍数是合数,具体不再赘述

    void primes(int n){
        memset(v,0,sizeof(v));
        for(int i=2;i<=n;++i)
        {
            if(v[i]) continue;
            prime[++cnt]=i;//i是质数
            for(int j=i*2;j<=n;j+=i) v[j]=1;
    	}
    }
    

    复杂度为(O(sum_{质数ple frac{N}{p}})=O(N log log N))

    线性筛法

    核心思想就是通过“从小到大积累质因子”的方式来标记合数,以此来避免(Eratosthenes)筛法重复标记合数的问题

    具体实现原理简单来说就是:每个合数(i*p)只会被它的最小质因子筛一次

    void primes(int n){
        memset(v,0,sizeof(v));//最小质因子
        cnt=0;//质数的数量
        for(int i=2;i<=n;++i)
        {
            if(v[i]==0) {prime[++cnt]=i;v[i]=i;}
            for(int j=1;j<=cnt;++j)
            {
                if(prime[j]>v[i]||prime[j]>n/i) break;
                v[i*prime[j]]=prime[j];
            }
        }
    }
    //于2020.7.6更正代码
    

    复杂度为(O(N))我一般都是用埃氏筛

    算术基本定理

    任何一个大于(1)的正整数都能被唯一分解为有限个质数的乘积的形式,写作:

    [N=p_1^{c_1}p_2^{c_2}...p_m^{c_m} ]

    其中(c_iinN^+),(p_i)都是质数,且满足(p_1<p_2<...<p_m)

    试除法分解质因数

    就是结合一下埃氏筛和试除法

    void divide(int n)
    {
        cnt=0;
        for(int i=2;i*i<=n;++i)
        {
            if(n%i==0)
            {
                p[++cnt]=i;c[cnt]=0;
                while(n%i==0) n/=i,c[cnt]++;
    		}
        }
        if(n>1) p[++cnt]=n,c[cnt]=1;
    }
    

    复杂度为(O( sqrt N ))

    约数

    算术基本定理的推论

    如果一个正整数被分解成了(N=p_1^{c_1}p_2^{c_2}...p_m^{c_m})这种形式,则(N)的正约数集合可以写作

    (p_1^{b_1}p_2^{b_2}...p_m^{b_m})其中(0le b_i le c_i)

    约数个数

    (N)的正约数个数为(prodlimits_{i=1}^m(c_i+1))

    约数和

    (N)的所有正约数和为(prodlimits_{i=1}^m(sumlimits_{j=0}^{c_i}(p_i)^j))

    (N)的正约数集合

    试除法

    核心就是利用约数总是成对出现(除了对于完全平方数,(sqrt{N})会单独出现)

    for(int i=1;i*i<=N;++i)
    {
        if(n%i==0)
        {
            d[++cnt]=i;
            if(i!=n/i) d[++cnt]=n/i;
    	}
    }
    

    复杂度为(O( sqrt N))

    试除法的推论

    一个正整数的约数个数上界为(2 sqrt N)

    倍数法

    (1acksim N)中每个数的正约数集合

    核心思路就是对于每个约数(d),以它为约数的正整数为(d,2d,3d...leftlfloordfrac{N}{d} ight floor*d)

    for(int i=1;i<=n;++i)
    	for(int j=1;j<=n/i;++j)
            f[i*j].push_back(i);
    

    复杂度为(O(N+frac{N}{2}+frac{N}{3}...+frac{N}{N})=O(Nlog N))

    倍数法推论

    (1acksim N)中每个数的约数个数的总和大约为(N log N)

    最大公约数

    定理

    (forall a,bin N gcd(a,b)*lcm(a,b)=a*b)

    更相减损法

    (forall a,bin N,age b gcd(a,b)=gcd(b,a-b)=gcd(a,a-b))

    (forall a,bin N gcd(2a,2b)=gcd(a,b))

    如果需要高精度计算时,高精度除法(取模)很恶心人,可以用更相减损法来替代欧几里得算法

    欧几里得法

    (forall a,bin N gcd(a,b)=gcd(b,a\%b))

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

    互质与欧拉函数

    欧拉函数

    定义

    (1acksim N)中与(N)互质的数的个数,记为(varphi(N))

    $varphi(N)=N*prodlimits_{质数p|N}(1-frac{1}{N}) $

    积性函数

    如果(a,b)互质时,有(f(ab)=f(a)*f(b)),那么函数(f)就是积性函数

    积性函数的性质

    (f)是积性函数,且在算术基本定理中(n=prod_{i=1}^mp_i^{c_i})(f(n)=prod_{i=1}^{m}f(p_i^{c_i}))

    欧拉函数基本性质
    1. (forall n>1,1acksim n)中与(n)互质的数的和为(n*varphi(n)/2)
    2. (a,b)互质,则(varphi(ab)=varphi(a)*varphi(b))(积性函数的性质)
    3. (p)是质数,若(pmid n)(p^2mid n),则(varphi(n)=varphi(n/p)*p)
    4. (p)是质数,若(pmid n)但是(p^2 mid n)(varphi(n)=varphi(n/p)*(p-1))
    5. (sum_{dmid n}varphi(d)=n)
    试除法求欧拉函数

    根据欧拉函数的计算计算式,可以在分解质因数时顺便求出欧拉函数

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

    复杂度为(O(sqrt N))

    (Eratosthenes)筛法求欧拉函数

    根据欧拉函数的计算式,可以在(O(n log n))的时间内求出(2 acksim n)中每个数的欧拉函数

    void euler(int n)
    {
        for(int i=2;i<=n;++i) phi[i]=i;
        for(int i=2;i<=n;++i)
            if(phi[i]==i)
                for(int j=i;j<=n;j+=i)
                    phi[j]=phi[j]/i*(i-1);
                
    }
    
    线性筛快速递推欧拉函数
    1. (p)是质数,若(pmid n)(p^2mid n),则(varphi(n)=varphi(n/p)*p)
    2. (p)是质数,若(pmid n)但是(p^2 mid n)(varphi(n)=varphi(n/p)*(p-1))

    利用上述性质,在线性筛每个合数(n)被最小质因子(p)筛掉的时候通过(varphi(n/p))递推到(varphi(n))

    代码就不写了,我没写过这种方法(我菜)

    同余

    同余,同余类和剩余系的定义

    自己百度吧,懒得写了(qwq)

    费马小定理

    (p)为质数,则对于任意整数(a),都有(a^p equiv a (mod p))

    欧拉定理

    若正整数(a,n)互质,则(a^{varphi(n)} equiv 1(mod n))

    欧拉定理的推论

    若正整数(a,n)互质,则(a^n equiv a^{n\% varphi(n)}(mod n))

    若正整数(a,n)不一定互质时,且(b> varphi (n))(a^b equiv a^{b\%varphi(n)+varphi(n)}(mod n))

    可用于欧拉降幂

    裴蜀定理

    对于任意整数(a,b),都存在一对整数(x,y),满足(ax+by=gcd(a,b))

    扩展欧几里得算法

    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 z=x;x=y;y=z-y*(a/b)
        return d;
    }
    

    注意

    上述程序求出方程(ax+by=gcd(a,b))的一组特解(x_0,y_0)

    对于更为一般的方程(ax+by=c)而言,当(dmid c)时方程有解,此时方程的解为((c/d)*x_0,(c/d)*y_0)

    方程(ax+by=c)的通解可以表示为:

    (x=frac{c}{d}x_0+kfrac{b}{d})

    (y=frac{c}{d}y_0-kfrac{a}{d})

    通过上式就可以求出最小正整数解了,(qwq)

    乘法逆元的计算和应用

    大概就是一个整数,能让(a/b)在模(p)的意义下等于(a*inv(b))

    然后就可以到处取模了,(qwq)

    逆元的计算
    根据费马小定理求解

    对于(a/b(mod p))而言

    (p)为质数,则根据费马小定理,(b^{p-1} equiv 1(mod p))

    (b*b^{p-2}equiv 1(mod p))

    (b^{p-2})即为(b)的乘法逆元

    求解同余方程

    如果只保证(b,p)互质,则可以通过直接求解同余方程(b*xequiv 1(mod p))

    线性递推逆元
    利用阶乘递推逆元

    由于(a=frac{a!}{(a-1)!})

    (a^{-1}equiv(a-1)!a!^{-1})

    ((a-1)!equiv a!^{-1}a)

    可以求出(1...k)的阶乘,然后利用快速幂求出(k!)的逆元,然后反推(1...k)的阶乘的逆元

    该方法也可以求出任意(k)个数的阶乘,即把阶乘换成前缀和


    [未完待续 ]


  • 相关阅读:
    【BZOJ4514】【SDOI2016】数字配对 [费用流]
    【BZOJ4517】【SDOI2016】排列计数 [数论]
    【BZOJ4516】【SDOI2016】生成魔咒 [SAM]
    【BZOJ1560】【JSOI2009】火星藏宝图 [DP]
    【BZOJ4903】【CTSC2017】吉夫特 [DP]
    【BZOJ3884】上帝与集合的正确用法 [欧拉定理]
    【BZOJ4869】相逢是问候 [线段树][欧拉定理]
    树和二叉树知识点总结
    Socket详解
    Host文件简介
  • 原文地址:https://www.cnblogs.com/pyyyyyy/p/12762576.html
Copyright © 2011-2022 走看看