详见代码例子:
#include<cstdio> #include<iostream> using namespace std;//ax+by=1 int Extend_Eulid(int b,int a)//(b,a)~(x,mod)~(b,a) { //初始化:X=(1,0,a); Y=(0,1,b) Y2对应y,也是最终的结果。 int x1,x2,x3,y1,y2,y3 ; x1=1,x2=0,x3=a,y1=0,y2=1,y3=b ; printf("%d*%d+%d*%d=%d\n",x1,a,x2,b,x3); printf("%d*%d+%d*%d=%d\n",y1,a,y2,b,y3); while(y3 && y3!=1) { int q=x3/y3 ; int t1,t2,t3 ; cout<<q<<endl; t1=x1-q*y1,t2=x2-q*y2,t3=x3-q*y3 ; x1=y1,x2=y2,x3=y3 ; y1=t1,y2=t2,y3=t3 ; printf("%d*%d+%d*%d=%d\n",y1,a,y2,b,y3); } if(!y3)return -1 ; return y2 ; } /* 两个式子不断相减,确保ax+by=c的右值c不断变小直至趋近1.最后得到的y2即是b关于1模a的乘法逆元。 */ int main(){ int x,mod; while(cin>>x>>mod){ int ans=Extend_Eulid(x,mod); printf("%d关于1模%d的乘法逆元是%d\n",x,mod,ans); } return 0; }
乘法逆元模板:
int Extend_Eulid(int b,int a)
{
int x1,x2,x3,y1,y2,y3 ;
x1=1,x2=0,x3=a,y1=0,y2=1,y3=b ;
while(y3 && y3!=1)
{
int q=x3/y3 ;
int t1,t2,t3 ;
t1=x1-q*y1,t2=x2-q*y2,t3=x3-q*y3 ;
x1=y1,x2=y2,x3=y3 ;
y1=t1,y2=t2,y3=t3 ;
}
if(!y3)return -1 ;
return y2 ;
}
另外,还需要快速幂取模:
int supower(int x,int p){
int ans=1;
while(p){
if(p&1)ans=ans*x%29;
x=x*x%29;
p=p>>1;
}
return ans;
}
代码:
#include <iostream> #include<cstdio> #include<cstring> using namespace std; int Extend_Eulid(int d,int f) { int x1,x2,x3,y1,y2,y3 ; x1=1,x2=0,x3=f,y1=0,y2=1,y3=d ; while(y3 && y3!=1) { int q=x3/y3 ; int t1,t2,t3 ; t1=x1-q*y1,t2=x2-q*y2,t3=x3-q*y3 ; x1=y1,x2=y2,x3=y3 ; y1=t1,y2=t2,y3=t3 ; } if(!y3)return -1 ; return y2 ; } int supower(int x,int p){ int ans=1; while(p){ if(p&1)ans=ans*x%29; x=x*x%29; p=p>>1; } return ans; } /*a=s(2^(2n))=(2^(2n+1)-1) b=s(3^n)=(3^(n+1)-1)/2 c=s(22^n)=(22^(n+1)-1)/21*/ int main() { int qb=Extend_Eulid(2,29),qc=Extend_Eulid(21,29); //freopen("cin.txt","r",stdin); int n; while(cin>>n&&n){ int a=supower(2,2*n+1)-1; int b=(supower(3,n+1)-1)*qb%29; int c=(supower(22,n+1)-1)*qc%29; printf("%d\n",a*b*c%29); } return 0; }