数论——同余,不定方程,CRT,高斯消元

同余

若两个整数 a a a b b b 除以 正整数 m m m 后余数相同,则说 a a a b b b 关于模 m m m 同余,记作:
a ≡ b ( m o d m ) a\equiv b \pmod m ab(modm)

同余的相关性质:

  1. a ≡ b ( m o d m ) , c ≡ d ( m o d m ) a\equiv b\pmod m,c\equiv d\pmod m ab(modm),cd(modm),则 a + c ≡ b + d ( m o d m ) a+c\equiv b+d\pmod m a+cb+d(modm)
  2. a ≡ b ( m o d m ) , c ≡ d ( m o d m ) a\equiv b\pmod m,c\equiv d\pmod m ab(modm),cd(modm),则 a c ≡ b d ( m o d m ) ac\equiv bd\pmod m acbd(modm)
  3. a ≡ b ( m o d m ) a\equiv b\pmod m ab(modm),则 a n ≡ b n ( m o d m ) a^n\equiv b^n\pmod m anbn(modm)
  4. a ≡ b ( m o d m ) a\equiv b\pmod m ab(modm),则 P ( a ) ≡ P ( b ) ( m o d m ) P(a)\equiv P(b)\pmod m P(a)P(b)(modm) P P P 为任意多项式

易错点:
a k ≡ b k ( m o d m ) ak\equiv bk\pmod m akbk(modm),则不一定 a ≡ b ( m o d m ) a\equiv b\pmod m ab(modm)

欧拉定理

表述:若正整数 n n n 与整数 a a a 互质,则满足 a ϕ ( n ) ≡ 1 ( m o d n ) a^{\phi(n)}\equiv 1\pmod n aϕ(n)1(modn)

n ∈ p r i m e s n\in primes nprimes,则退化为费马小定理 a n − 1 ≡ 1 ( m o d n ) a^{n-1}\equiv 1\pmod n an11(modn)

费马小定理快速幂指数取模(mod-1)分数取模求乘法逆元的依据.

整除性特征

  1. 4 4 4 25 25 25 整除的特征是末二位数字能被 4 4 4 25 25 25 整除.
  2. 8 8 8 125 125 125 整除的特征是末三位数字能被 8 8 8 125 125 125 整除.
  3. 9 9 9 整除的特征是各位数字和能被 9 9 9 整除.
  4. 99 99 99 整除的特征是两位一段的所有数段和能被 99 99 99 整除.

裴蜀定理

a , b a,b a,b 是整数,且 ( a , b ) = d (a,b)=d (a,b)=d,则对于任意的整数 x , y x,y x,y a x + b y ax+by ax+by d d d 的倍数.

裴蜀定理的作用:不定方程 a x + b y = c ax+by=c ax+by=c 有整数解,则 ( a , b ) ∣ c (a,b)|c (a,b)c

不定方程的通解(特解+齐次的通解)
x 0 , y 0 x_0,y_0 x0,y0 是方程 a x + b y = c ax+by=c ax+by=c 的一组整数解,则所有整数解为(通解):
{ x = x 0 + b ( a , b ) t y = y 0 − a ( a , b ) t \begin{cases} x =x_0+\frac{b}{(a,b)}t \\ y=y_0-\frac{a}{(a,b)}t \end{cases} {x=x0+(a,b)bty=y0(a,b)at

扩展欧几里得算法

本质裴蜀定理,直接上板子

ll exgcd(ll a,ll b,ll& x,ll& y)		//一定带引用
{
	if(!b)
	{
		x=1,y=0;
		return a;
	}
	
	ll d=exgcd(b,a%b,y,x);
	y-=a/b*x;
	
	return d;
} 

线性同余方程

例1:AcWing 878

在这里插入图片描述

思路

本题的本质是解同余方程 a x + m y = b ax+my=b ax+my=b,那么先解方程 a x + m y = g c d ( a , m ) ax+my=gcd(a,m) ax+my=gcd(a,m) (扩展欧几里得)
得到 a x 0 + m y 0 = d ax_0+my_0=d ax0+my0=d

首先判断 d d d 是否整除 b b b

随后构造方程 a X + m Y = b aX+mY=b aX+mY=b 的形式,即
a ( x 0 b d ) + m ( y 0 b d ) = b a(\frac{x_0b}{d})+m(\frac{y_0b}{d})=b a(dx0b)+m(dy0b)=b

那么 x x x 的通解就为 x = x 0 b d + t ∣ m d ∣ x=\frac{x_0b}{d}+t|\frac{m}{d}| x=dx0b+tdm

ll a,b,m;

ll exgcd(ll a,ll b,ll& x,ll& y)
{
	if(!b)
	{
		x=1,y=0;
		return a;
	}
	
	ll d=exgcd(b,a%b,y,x);
	y-=a/b*x;
	
	return d;
}

ll gcd(ll a,ll b)
{
	return b ? gcd(b,a%b) : a;
}

int main()
{
	int i,n;
	ll x,y,d,mod;
	
	n=read();
	while(n--)
	{
		a=read(),b=read(),m=read();
		d=exgcd(a,m,x,y);
		if(b%d)	puts("impossible");
		else
		{
		    x=x*b/d;
			mod=abs(m/d);
			printf("%lld\n",(x%mod+mod)%mod);
		}
	}
	
	return 0;
}

中国剩余定理

本质上就是解线性同余方程组.
就是一行一行解,要注意随时取模,防止溢出.

注意: C R T CRT CRT 有解的条件是:模数两两互质

在这里插入图片描述

ll exgcd(ll a,ll b,ll& x,ll& y)
{
    if(!b)
    {
        x=1,y=0;
        return a;
    }
    
    ll d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    
    return d;
}

int main()
{
	int i,n;
	ll a1,m1,a2,m2,a3,m3,x,y,d,mod;
	
	n=read();
	a1=read(),m1=read();
	
	rep(i,2,n)
	{
		a2=read(),m2=read();
		
		m2=(m2%a2+a2)%a2;
		
		d=exgcd(a1,-a2,x,y);
		if((m1-m2)%d)
		{
			printf("%d",-1);
			return 0;
		}
		
		x=(m1-m2)/d*x;
		x=(x%(a2/d)+a2/d)%(a2/d);
		
		a3=-a1*a2/d;
		m3=m1-a1*x;
		
		swap(a1,a3),swap(m1,m3);
		
		a1=abs(a1);                     //注意使得m变为正的
		m1=(m1%a1+a1)%a1;			    //使得 m 最小化 
	}
	
	printf("%lld",m1);
	
	return 0;
}

公式法求 C R T CRT CRT:
在这里插入图片描述

高斯消元

高斯消元,直接上板子

const int N=110;
const ld epsl=1e-8;
int n;

ld a[N][N];

int guass()
{
	int i,j,r=1,c,tp;
	
	rep(c,1,n)
	{
		tp=r;													/*****标准六部曲*****/ 
		rep(i,r+1,n)	if(fabs(a[i][c])>fabs(a[tp][c]))	tp=i;	//找主元
		if(fabs(a[tp][c])<epsl)	continue;							//若为0,继续 
		rep(i,c,n+1)	swap(a[tp][i],a[r][i]);						//交换 
		repf(i,n+1,c)	a[r][i]/=a[r][c];							//把主元变成1
		rep(i,r+1,n)	repf(j,n+1,c)	a[i][j]-=a[i][c]*a[r][j];	//用第一行去减下面的 icrj
		++r;														//别忘了 
	}
	
	if(r<c)
	{
		//检查接下来行的情况 
		rep(i,r,n)	if(fabs(a[i][n+1]>epsl))	return -1;
		return 0;	
	}
	
	repf(i,n,2)	repf(j,i-1,1)	a[j][n+1]-=a[i][n+1]*a[j][i]; //ji
	return 1;
}

int main()
{
	int i,j;
	
	n=read();
	rep(i,1,n)	rep(j,1,n+1)	scanf("%Lf",&a[i][j]);
	
	int res=guass();
	
	if(res==-1)	puts("No solution");
	else if(res==0) puts("Infinite group solutions");
	else	rep(i,1,n)	printf("%.2Lf\n",fabs(a[i][n+1])<epsl ? 0 : a[i][n+1]);
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值