数学知识入门

定理1算术基本定理:任何大于1的正整数都可以唯一分解为有限个质数的乘积

N=p1c1p2c2…pmcm

质数

试除法判断质数

时间复杂度 O( n \sqrt{n} n )
证明:为什么可以只判断到根号n?如果a小于等于 n \sqrt{n} n ,同时a是n的因子,那么对应的n/a是大于等于 n \sqrt{n} n 的,所以只需要判断小于的那部分即可

代码

bool isprime(int x) 
{
    if (x < 2) return false;
    for (int i = 2; i <= x / i; i ++ )
        if (x % i == 0)
            return 0;
    return 1;
}

分解质因数

时间复杂度O( n \sqrt{n} n )
证明:一个数n最多有一个大于 n \sqrt{n} n 的因子,如果大于一个,那么这两个数相乘大于n,矛盾

代码:

void div(int x)
{
    for(int i=2;i<=x/i;i++)
    {
        if(x%i==0)
        {
            int cnt=0;
            while(x%i==0)
            x/=i,cnt++;
            cout<<i<<" "<<cnt<<endl;
        }
    }
    if(x>1) cout<<x<<" "<<1<<endl;
}

筛质数

埃式筛法

思想:对于x,他的倍数都是合数,只需要将素数的倍数都标记为合数就可以
时间复杂度O(NloglogN)
分析:首先对于数x,他的倍数有 N x \frac{N}{x} xN个,x的范围是从2到N,所以是 ∑ i = 2 N \sum_{i=2}^N i=2N N i \frac{N}{i} iN,根据调和级数,此时时间复杂度为NloglogN,1到N中大约有N/lnN个素数,时间复杂度为NloglogN

代码:

void get_primes(int n)
{
    int cnt=0;
    for(int i=2;i<=n;i++)
    {
        if(!st[i])
        {
            cnt++;
            for(int j=2;j*i<=n;j++) st[j*i]=true;
        }
    }
    cout<<cnt<<endl;
}

线性筛,虽然埃氏筛法已经接近线性,但是当n在1e7,线性筛运行时间大概是埃氏筛的一半

思想:仅仅使用某个数的最小质因子来标记
时间复杂度O(N)

代码:

void get_primes(int n)
{
    int cnt=0;
    for(int i=2;i<=n;i++)
    {
        if(!st[i])
        {
            prim[cnt++]=i;
        }
        for(int j=0;prim[j]*i<=n&&j<cnt;j++)
        {
            st[prim[j]*i]=true;
            if(i%prim[j]==0) break;
        }
    }
    cout<<cnt<<endl;
}

约数

约数个数

由算数基本定理可以得知n的一个约数可以写做p1ip2j…pmk,0<=i<=c1,0<=j<=c2…0<=k<=cm
结论:所以个数为(1+c1)(1+c2)…(1+cm)

代码:

    cin>>t;
    map<int,int> cnt;
    ll ans=1;
    while(t--)
    {
        cin>>n;
        for(int i=2;i<=n/i;i++)
        {
            if(n%i==0)
            {
                while(n%i==0)
                cnt[i]++,n/=i;
            }
        }
        if(n>1) cnt[n]++;
        
    }
    for(auto x:cnt)
    {
        ans*=(x.second+1);
        ans%=mod;
    }
    cout<<ans<<endl;

约数之和

结论:ans=(p10+p11+…p1c1)(p20+p21+…p2c2)…(pm0+pk1+…pkck
证明:将该式展开可以得到所有的约数

代码:

cin>>t;
    unordered_map<int,int> hash;
    while(t--)
    {
        cin>>n;
        for(int i=2;i<=n/i;i++)
        {
            if(n%i==0)
            {
                int s=0;
                while(n%i==0)
                {
                    s++;
                    n/=i;
                }
                hash[i]+=s;
            }
        }
        if(n>1)hash[n]+=1;
    }
    ll ans=1;
    for(auto x: hash)
    {
        ll res=1;
        ll add=x.x;
        for(int i=1;i<=x.y;i++)
        {
            res+=add;
            res%=mod;
            add*=x.x;
            add%=mod;
        }
        ans=ans*res%mod;
    }
    cout<<ans<<endl;

欧拉函数

定义:1到N中与N互质的个数称为N的欧拉函数,记作 ϕ \phi ϕ(N)

结论 ϕ \phi ϕ(N)=N( p 1 − 1 p 1 \frac{p1-1}{p1} p1p11)( p 2 − 1 p 2 \frac{p2-1}{p2} p2p21)…( p m − 1 p m \frac{pm-1}{pm} pmpm1)

证明:根据容斥原理,首先应该减去p1到pm的倍数,发现pipj的倍数减去了两次,那么应该在加上一个,然后可以发现pipj*pk的倍数分别在减去了三次加上了三次,所以应该在减去一次,得到规律,减去奇数项相乘,加上偶数项相乘,得到的就是结论中的公式

代码:

cin>>x;
        ll res=x;
        for(int i=2;i<=x/i;i++)
        {
            if(x%i==0)
            {
                res=res*(i-1)/i;
                while(x%i==0)
                x/=i;
            }
        }
        if(x>1)res=res*(x-1)/x;
        cout<<res<<endl;

定理2欧拉定理:如果gcd(a,m)等于1,那么a^ ϕ \phi ϕ(m) ≡ \equiv 1 ( m o d m ) \pmod{m} (modm)

逆元:当涉及到除法取模时经常需要用到逆元,ab%p=ab-1%p ,b*b-1 ≡ \equiv 1 ( m o d m ) \pmod{m} (modm)

证明当m是质数时,那么 ϕ \phi ϕ(m)=m-1,所以b(m-1) ≡ \equiv 1 ( m o d m ) \pmod{m} (modm) ,也就是b * b(m-2) ≡ \equiv 1 ( m o d m ) \pmod{m} (modm) ,所以b(m-2)就是b模m时的乘法逆元

扩展欧几里得

给定 n 对正整数 ai,bi,对于每对数,求出一组 xi,yi,使其满足 ai×xi+bi×yi=gcd(ai,bi)。

因为ai=kgcd,bi=kgcd,所以一定有解
运算过程,当a或者b其中有一个为0时,gcd为a与b中非0的那个,x与y分别就是0和1,由于gcd(a,b)=gcd(b,a%b)
假设存在一组x1和y1,使得b*x1+(a%b)*y1=gcd(b,a%b)=gcd(a,b)
bx1+(a-b* ⌊ \lfloor a b \frac{a}{b} ba ⌋ \rfloor )y1=gcd(a,b)
通过递归可以求得x和y

代码

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

求解线性同余方程

给定 n 组数据 ai,bi,mi,对于每组数求出一个 xi,使其满足 ai×xi≡bi(modmi)

ax-b是m的倍数可得 ax+my=b,即为上述exgcd
  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值