数论,
上来是最大公约数与最小公倍数,怎么算最大公约数?两种方法一个是欧几里得算法,一个是stein算法,
欧几里得算法:
int gcd(int a,int b)
{
while(b)
{
int r=a%b;
a=b;
b=r;
}
return a;
}
{
while(b)
{
int r=a%b;
a=b;
b=r;
}
return a;
}
stein算法:
int gcd(int a,int b)
{
int r=0;
while(b)
{
if(a%2==0&&b%2==0)
{
r=r+1;
a>>=1;
b=(b>>1);
}
else if(a%2==0)
a>>=1;
else if(b%2==0)
b>>=1;
else
{
a=a-b;
}
if(a>b)
swap(a,b);
}
return a<<r;
}
{
int r=0;
while(b)
{
if(a%2==0&&b%2==0)
{
r=r+1;
a>>=1;
b=(b>>1);
}
else if(a%2==0)
a>>=1;
else if(b%2==0)
b>>=1;
else
{
a=a-b;
}
if(a>b)
swap(a,b);
}
return a<<r;
}
然后是用扩展欧几里得算法求解二元模线性方程
ax+by=c;
gcd(a,b)|c时方程才有整数解
对方程先约分,在求解
int gcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int ans=gcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return ans;
}
{
if(b==0)
{
x=1;
y=0;
return a;
}
int ans=gcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return ans;
}
x=x0+b/gcd(a,b)*k;
y=y0-a/gcd(a,b)*k
中国剩余定理则是解多个二元模线性方程,是解同余方程组
x=a1modm1;
x=a2modm2;
x=anmodmn;
Mixi=_1modmi;
M=m1m2...mn;
Mi=M/mi;
void gcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return ;
}
gcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
}
int gcd(int a[],int m[],int n)
{
int ans=0;
int M=1;
for(int i=1;i<=n;i++)
M=M*m[i];
for(i=1;i<=n;i++)
{
int x,y;
Mi=M/m[i];
gcd(Mi,m[i],x,y);
ans=(ans+a[i]*x*Mi)%M;
}
while(ans<0)
ans+=M;
return ans;
}
x=a2modm2;
x=anmodmn;
Mixi=_1modmi;
M=m1m2...mn;
Mi=M/mi;
void gcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return ;
}
gcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
}
int gcd(int a[],int m[],int n)
{
int ans=0;
int M=1;
for(int i=1;i<=n;i++)
M=M*m[i];
for(i=1;i<=n;i++)
{
int x,y;
Mi=M/m[i];
gcd(Mi,m[i],x,y);
ans=(ans+a[i]*x*Mi)%M;
}
while(ans<0)
ans+=M;
return ans;
}