基本定理与概念
形如\(a\equiv b(mod\;m)\)的式子称为同余式
- \(a\equiv b(mod\;m)\)当且仅当\(m\;|\;(a-b)\)
- 若\(a\equiv b(mod\;m)\),\(b\equiv c(mod\;m)\),则\(a\equiv c(mod\;m)\)(传递性)
- 若\(a\equiv b(mod\;m)\),则
- \(a+c\equiv b+c(mod\;m)\)
- \(a-c\equiv b-c(mod\;m)\)
- \(a\times c\equiv b\times c(mod\;m)\)
- 若\(a\equiv b(mod\;m)\),\(c\equiv d(mod\;m)\)
- \(ax+cy=bx+dy(mod\;m)\)
- \(a\times c\equiv b\times d(mod\;m)\)
- \(a^n\equiv b^n(mod\;m)\)
- \(f(a)\equiv f(b)(mod\;m)\)
- 若\(a\equiv b(mod\;m)\),且\(d\;|\;m\),则\(a\equiv b(mod\;d)\)
线性同余方程
形如\(ax\equiv b(mod\;m)\)的包含未知数的同余式称为一元线性同余方程
- 若\(gcd(a,m)=d\),如果\(d\;|\;b\),则方程有d个模m不同的解,否则无解
- 求解一元线性同余方程需要使用扩展欧几里德算法,过程如下: 设\(a=d\times a_0\),\(m=d\times m_0\),方程变为:\(a_0x+m_0y=b\;/\;d\)
void exgcd(ll a,ll b,ll &d,ll &x,ll &y){ if(b==0){ x=1;y=0; d=a;return; }else{ exgcd(b,a%b,d,x,y); ll tmp=x; x=y; y=tmp-(a/b)*y; }}int solve(int a,int b,int m){ exgcd(a,m,d,x,y); if(b%d) return -1; //无解 x=x*(b/d)%m; for(int i=1;i<=d;i++) ans[i]=(x+(i-1)*m/d)%m;}
设同余方程组为
\[ \begin {aligned} x&=r_1(mod\;a_1)\\\ x&=r_2(mod\;a_2)\\\ x&=r_3(mod\;a_3)\\\ x&=r_4(mod\;a_4)\\\ &\cdots\\\ x&=r_5(mod\;a_5)\\\ \end {aligned} \] 求解一元线性同余方程组(小于m的非负整数解),求解x,例题【POJ 2891】void exgcd(ll a,ll b,ll &d,ll &x,ll &y){ if(b==0){ x=1;y=0; d=a; }else{ exgcd(b,a%b,d,y,x),y-=x*(a/b); }}int a[N],r[N],n;ll solve(){ ll ta=a[1],tr=r[1],x,y,d; for(int i=2;i<=n;i++){ exgcd(ta,a[i],d,x,y); if((r[i]-tr)%d) return -1; x=(r[i]-tr)/d*x%(a[i]/d); tr+=x*ta;ta=ta/d*a[i]; tr%=ta; } return tr>0?tr:tr+ta;}