数论入门 2021-2-28

一、

模运算

当答案或者运算过程中数据太大,题目要求输出答案对某个大数据取模,
有以下结论:

(a+b)%MOD=(a%MOD+b%MOD)%MOD
(a-b)%MOD=(a%MOD-b%MOD)%MOD
(a*b)%MOD=(a%MOD*b%MOD)%MOD
而除法取模需要逆元,后面会介绍

c++语言取模过程中,会遵循商尽量大的原则,所以(-5)%3=-2
这个不符合数学上取模的标准,因此使用c++对减法取模应该写成:

(a-b+MOD)%MOD

二、质数

1~n当中,大约有 n l n ( n ) \frac{n}{ln(n)} ln(n)n个质数

1、质数筛

埃氏筛
复杂度为O(nlg(lg(n)))

const int maxn=1e6;
int prime[maxn];
bool vis[maxn];
int cnt=0;
void Prime(int n){
    for(int i=2;i<=n;i++){
        if(!vis[i]){
            prime[++cnt]=i;
            for(int j=i*i;j<=n;j+=i){
                vis[j]=true;
            }
        }
    }
}

//此处有个小优化,嵌套的循环内 j j j i ∗ i i * i ii 开始,而不是 i + i i + i i+i开始,因为 i ∗ ( 2 − > i − 1 ) i*(2 ->i-1) i(2>i1)在这之前都已经被筛去。

欧拉筛
复杂度O(n)

const int maxn=1e6;
int prime[maxn];
bool vis[maxn];
int cnt=0;
void Prime(int n){
    for(int i=2;i<=n;i++){
        if(!vis[i]){
            prime[++cnt]=i;
        }
        for(int j=1;prime[j]*i<=n;j++){
            vis[prime[j]*i]=true;
            if(i%prime[j]==0){
            //保证每个合数都用该数最小的质因子筛掉
            //当i%prime[j]==0的时候,说明如果j继续加一,被筛掉的数就不是用其最小的质因子筛去的了。
                break;
            }
        }
    }
}

2、质因数分解----试除法

任意正整数 n n n最多有一个比 s q r t ( n ) sqrt(n) sqrt(n)大的质因子,质因数分解模版如下:
(⁎⁍̴̛ᴗ⁍̴̛⁎)
质因数分解模版

int pdivid[10000];
int cnt=0;//记录一共有多少个质因子
void divid(int n){
    for(int i=2;i<=n/i;i++){
        if(n%i==0){
            //此处i一定为质数
            pdivid[++cnt]=i;
            int s=0;
            while(n%i==0){
                n/=i;
                s++;//可以计算每个质因子出现的次数,这份代码不记录这个数
            }
        }
    }
    if(n>1){
        pdivid[++cnt]=n;
    }
}
int main(){
    int n;
    cin>>n;
    divid(n);
    cout<<pdivid[cnt]<<endl;
}

三、约数

1、试除法

直接枚举从1~sqrt(n)所有的数字,可以得到n所有的约数。
每个数的约数个数期望为lg(n).

2、约数个数和约数之和

先对N进行质因数分解,假设分解后:
o(`ω´ )o:::::

N = = p 1 c 1 ∗ p 2 c 2 ∗ . . . ∗ p k c k N== p_1^{c_1} * p_2^{c_2} * ... *p_k^{c_k} N==p1c1p2c2...pkck

(pi为质因子,ci为质因子对应的次数)

那么N的约数个数为::
( c 1 + 1 ) ∗ ( c 2 + 1 ) ∗ . . . ∗ ( c k + 1 ) (c1 + 1) * (c2 + 1) * ... * (ck + 1) (c1+1)(c2+1)...(ck+1)

N的约数之和为::
( p 1 0 + p 1 1 + . . . + p 1 c 1 ) ∗ . . . ∗ ( p k 0 + p k 1 + . . . + p k c k ) (p_1^0 + p_1^1 + ... + p_1^{c_1}) * ... * (pk^0 + pk^1 + ... + pk^{c_k}) (p10+p11+...+p1c1)...(pk0+pk1+...+pkck)
(把上式子展开后,直接看出为计算每个约数的和)

const int mod=1e9+7;
int main(){
    int n;
    cin>>n;
    
    unordered_map<int,int> primcnt;
    while(n--){
        int x;
        cin>>x;
        
        for(int i=2;i<=x/i;i++){
            while(x%i==0){
                x/=i;
                primcnt[i]++;
            }
        }
        
        if(x!=1){
            primcnt[x]++;
        }
    }
    
    ll ans=1;
    //遍历map
    for(auto prim:primcnt){
        ans=(ans*(prim.second+1))%mod;
    }
    cout<<ans<<endl;
}

3、最大公约数(gcd)

欧几里得算法

g c d ( a , b ) = g c d ( b , a gcd(a,b)=gcd(b,a%b) gcd(a,b)=gcd(b,a

(好神奇啊!)ʕ •ᴥ•ʔ

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

四、欧拉函数

1、定义
欧拉函数是小于n的正整数中与n互质的数的数目(比如 φ ( 1 ) = 1 φ(1)=1 φ(1)=1

2、公式
φ ( N ) = N ∗ ( 1 − 1 p 1 ) ∗ . . . . . ∗ ( 1 − 1 p i ) φ(N)=N*(1-\frac{1}{p_1}) * ..... * (1-\frac{1}{p_i}) φ(N)=N(1p11).....(1pi1)
其中 p i p_i pi N N N的质因子。

3、筛法求1~n的欧拉函数

void get_eulers(int n){
    //得到1~n所有欧拉函数的值
    //其实是欧拉筛变体
    int cnt=0;
    
    phi[1]=1;
    
    for(int i=2;i<=n;i++){
        if(!vis[i]){
            prim[++cnt]=i;
            //如果这个数是个素数,显然在1~i之间,有i-1个数与其互质
            phi[i]=i-1;
        }
        
        for(int j=1;prim[j]*i<=n&&j<=cnt;j++){
            vis[i*prim[j]]=1;
            if(i%prim[j]==0){
                //如果prim[j]是i的因子
                //根据公式,phi[i]=i*(1-1/P1)*...*(1-1/Pi)
                //i*prim[j]的所有因子跟i相同
                //phi[i*prim[i]]=prim[i]*i*(1-1/P1)*...*(1-1/Pi)=phi[i]*prim[i]
                phi[i*prim[j]]=phi[i]*prim[j];
                break;
            }
            //如果prim[j]不是i的因子
            //那么i*prim[j]的因子与i相差一个prim[j]
            //phi[i*prim[i]]=phi[i]*prim[j]*(1-1/prim[j])=phi[i]*phi[prim[j]]
            phi[i*prim[j]]=phi[i]*(prim[j]-1);
        }
    }
}

欧拉定理

如果a与n互质,那么 a p h i ( n ) ≡ 1 ( m o d n ) a^{phi(n)}≡1(mod n) aphi(n)1(modn).

四、快速幂

ll my_pow(int a,int k,int p=1e9+7){
    ll res=1;
    while(k){
        if(k&1){
            //如果k不能整除2
            res=(res*a)%p;
        }
        k>>=1;
        a=(a*a)%p;//让底数平方
    }
    return res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KaaaterinaX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值