蒟蒻这几天比较闲,于是自学了早就学了很久的扩欧与中国剩余定理。。。。。。
--------------------------------------------------------------------------------------------------------------扩展欧几里德------------------------------------------------------------------------------------------------------- 扩展欧几里德算法(用于求解px+qy=gcd(p,q)类问题):
px+qy=gcd(p,q) 记n=gcd(p,q) 则:
y=(n-px)/q=[n-(p mod q)x]/q-[p/q]x (p mod q=p-[p/q])
记y0=x x0=[n-(p mod q)x]/q=[n-(p mod q)y0]/q
其等价于 qx0+(p mod q)y0=n-(p mod q)y0+(p mod q)y0=n
递归求解即可; code(求ax+by=gcd(a,b)的一组可行解):
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int a,b,x,y;
void exgcd(int a,int b)
{
int t;
if (a%b==0)
{
x=0; y=1;
}
else
{
exgcd(b,a%b);
t=x; x=y; y=t-(a/b)*y;
}
}
int main()
{
scanf("%d%d",&a,&b);
exgcd(a,b);
printf("%d %d\n",x,y);
}
若要求解最小正整数,分别将x,y对lcm(a,b)取模 (lcm(a,b)*gcd(a,b)=a*b)
那么,我们既可以解决类似于 ax=c (mod b) 的同余方程最小解(满足 c|gcd(a,b))
我们可以将ax=c (mod b) 转化为 ax+by=c 的最小解,那么我们可以求出 ax+by=gcd(a,b) 再将 x 乘上 c/gcd(a,b) 即可(最后模去b)
code:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int a,b,c,x,y,gcd;
void exgcd(int a,int b)
{
int t;
if (a%b==0)
{
x=0; y=1;
gcd=b;
}
else
{
exgcd(b,a%b);
t=x; x=y; y=t-(a/b)*y;
}
}
int main()
{
scanf("%d%d%d",&a,&b,&c);
exgcd(a,b);
x=(x%b+b)%b;
x=x*(c/gcd);
x%=b;
printf("%d\n",x);
}
那么我们就解决了线性同余方程,那么问题来了,线性同余方程组怎么办?
-------------------------------------------------------------------------------------------------------中国剩余定理--------------------------------------------------------------------------------------------------------------
远离不再赘述,我在此只给出总式
已知 x=b1(mod m1) x=b2(mod m2)......x=bi(mod mi)......x=bn(mod mn) N=m1+m2+m3+........+mn
则x=
exgcd(a,b)返回以上程序的x
code:
#include<cstdio>
using namespace std;
int b[100],m[100];
int n,x,y,N;
void exgcd(int a,int b)
{
int t;
if (a%b==0)
{
x=0;
y=1;
}
else
{
exgcd(b,a%b);
t=x;
x=y;
y=t-(a/b)*y;
}
}
int main()
{
int i,now,ans;
scanf("%d",&n); N=1; ans=0;
for (i=1;i<=n;++i)
{
scanf("%d%d",&b[i],&m[i]);
N=N*m[i];
}
for (i=1;i<=n;++i)
{
now=N/m[i];
now=now%m[i];
exgcd(now,m[i]);
x=(x%m[i]+m[i])%m[i];
x=(x*(N/m[i])*b[i])%N;
ans=(ans+x)%N;
}
printf("%d\n",ans);
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Lcomyn