[NKNY]寒假培训复习

 NKNY寒假培训

[供自己复习,供大家参考]

如果有不对的地方请指出

另外:全文采用int,但实际上平时都是long long请注意

本次培训全是数论题

建议先学“质数基础”做铺垫

(虽然没多大关系)

目录
1.欧拉 求phi
2.Selcet_Euler 求phi
3.线性 求phi
4.扩欧
5.逆元
6.miller_rabin素数测试
7.二分快速幂
8.快速乘法 
9.线性求逆元
10.中国剩余定理
11.打表求排列
12.打表求组合
13.第二类斯特林数 
14.第一类斯特林数 
15.Bell数(懒得写代码)
16.

大组合数取模--Lucas定理 

附录:玄学--miller_rabin素数测试

1. 欧拉 求phi

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

 2.Selcet_Euler

void Selcet_Euler(int n){
    for(int i=1;i<=n;i++)phi[i]=i;
    for(int i=2;i<=n;i++){
        if(phi[i]==1){
            for(int j=1;j<=n;j+=i){
                phi[j]=phi[j]/i*(i-1);
            }
        }
    }
}

3. 线性 欧拉 求phi

void gp(){
    int tot;
    for(int i=2;i<=n;i++){
        if(mark[i]==0){
            pr[++tot]=i;
            phi[i]=i-1;
        }
        for(int j=1;j<=tot&&pr[j]<=n;j++){
            mark[i*pr[j]]=1;
            if(i%pr[i]==0){
                phi[i*pr[j]]=phi[i]*pr[j];
                break;
            }else phi[i*pr[j]]=phi[i]*(pr[j]-1);
        } 
    }
}

4.扩欧

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

5.逆元

int ni(int a,int n){
    int x,y;
    if(exgcd(a,n,x,y)==1)return (x+n)%n;
    else return -1; 
}

6. miller_rabin

bool mr(int n){
    int a,x,y,d,r=0;
    if(n==2)return 1;
    if(n<2||n%2==0)return 0;
    d=n-1;
    while(d%2==0){
        d/=2;
        r++;
    }
    for(int i=1;i<=10;i++){
        a=rand()%(n-2)+2;
        x=ksm(a,d,n);
        for(int i=1;i<=r;i++){
            y=x*x%n;
            if(y==1&&x!=1&&x!=n-1)return 0;
            x=y;
        }
        if(x!=1)return 0;
    }
    return 1;
}

7.二分快速幂

int ksm(int a,int b,int mod){
    int ans=1;
    a%=mod;
    while(b){
        if(b%2==1)ans=ans*a%mod;
        a=a*a%mod;
        b/=2;
    }
} 

8.快速乘法 

int ksc(int a,int b,int mod){
    int ans=0;
    a%=mod;
    while(b){
        if(b%2==1)ans=(ans+a)%mod;
        a=a*2%mod;
        b/=2;
    }
}

9.线性逆元

inv[0]=inv[1]=1;
for(int i=2;i<=n;i++){
    inv[i]=(p-p/i)*inv[p%i]%p;
}

10.中国剩余定理

int china(int *b,int *w,int k){
    int d,x,y,ans=0,mi,p=1;
    for(int i=1;i<=k;i++)p*=w[i];
    for(int i=1;i<=k;i++){
        mi=p/w[i];
        d=ext_euclid(mi,w[i],x,y);
        ans=(ans+x*mi*b[i])%p;
    }
    if(ans>0)return ans;
    else return (ans+p)%p;
}

11.排列

int a[1001][1001];
for(int i=1;i<=n;i++){
    a[i][0]=1;
}
for(int i=1;i<=n;i++){
    for(int j=1;j<=i;j++){
        a[i][j]=(a[i-1][j-1]*i)%k;
        //a[i][j]=(a[i-1][j]*(i-j+1))%k;
    }
}

12.组合

int c[1001][1001];
for(int i=1;i<=n;i++){
    c[i][0]=1;
}
for(int i=1;i<=n;i++){
    for(int j=1;j<=i;j++){
        c[i][0]=(c[i-1][j]+c[i-1][j-1])%k;
    }
}

13.第二类斯特林数 

void getStirlng(){
    for(int i=1;i<=n;i++)s2[i][1]=1;
    for(int i=1;i<=n;i++){
        for(int j=2;j<=i&&j<=m;j++){
            s2[i][j]=(s2[i-1][j-1]+j*s2[i-1][j])%mod;
        }
    }
}

14.第一类斯特林数 

void getStirlng(){
    for(int i=0;i<=n;i++)s1[i][i]=1;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i&&j<=m;j++){
            s1[i][j]=(s1[i-1][j-1]+(i-1)*s1[i-1][j])%mod;
        }
    }
}

15. Bell数(懒得写代码了)

按 第二类斯特林数  

B[n]=S2[n][1]+S2[n][2]+...+S2[n][N];

16.大组合数取模--Lucas定理 

//Tips:p为全局变量,相当于 mod 
int KSM(int a,int b){...}//见上 
int C(int a,int b){
    if(a<b)return 0;
    if(a==b)return 1;
    if(b>(a-b))b=a-b;
    int A=1,B=1;
    for(int i=0;i<b;i++){
        A=(A*(a-i))%p;
        B=(B*(b-i))%p;
    }
    return (A*KSM(B,p-2))%p;
} 
int lucas(int n,int m){
    if(m==0)return 1;
    return C(n%p,m%p)*lucas(n/p,m/p);
}

附录:miller_rabin素数测试 毕竟是测试,准确性为75%

        所以!!!

玄学:

n<=2^3^2 时 只需测试a=2,7,61

n<=2^6^4 时 只需测试a=2,3,5,7,11

随机C次 错误率为 1/4^c

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值