求逆元的3種方法
阿新 • • 發佈:2018-12-11
//擴充套件歐幾里得求逆元 //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); } } } }