1. 程式人生 > >求逆元的3種方法

求逆元的3種方法

//擴充套件歐幾里得求逆元
//a*x=1(mod m)=>a*x+m*y=1
int extgcd(int a,int b,int &x,int &y){
    int d=a;
    if(b!=0){
        d=extgcd(b,a%b,y,x);
        y-=(a/b)*x;
    }
    else {
        x=1;y=0;
    }
    return d;
}
int mod_inv(int a,int m){
    int x,y;
    extgcd(a,m,x,y);
    return (x%m+m)%m;
}
//模數是素數:用費馬小定理:若m為素數,則x的逆元是x^(m-2)=>快速冪求解
//模數不是素數:尤拉定理:x的逆元是x^(f(x)-1),f(x)是x的尤拉函式值
int euler(int n){//求尤拉函式值
    int res=n;
    for(int i=2;i*i<=n;i++){
        if(n%2==0){
            res=res/i*(i-1);
            for(;n%i==0;n/=i);
        }
    }
    if(n!=1)res=res/n*(n-1);
    return res;
}
int euler[MAX_N];
void euler_1(){//篩出尤拉函式值的表
    for(int i=0;i<MAX_N;i++)euler[i]=i;
    for(int i=2;i<MAX_N;i++){
        if(euler[i]==i){
            for(int j=i;j<MAX_N;j+=i){
                euler[j]=euler[j]/i*(i-1);
            }
        }
    }
}