数论初步

质数合数

质数定义

除了1和它本身以外不再有其他因数的数

注意

1既不是质数也不是合数;

2是最小的质数,且是唯一的偶质数。

证明:

假设素数只有有限个,按照大小顺序,.分别记为:.。最大的素数.。

设所有乘积加1为s

如果s是素数,与假设矛盾。

如果s是合数,s不能被已知素数整除。得出矛盾。

筛素数

试除法:若一个正整数n为合数,则存在一个能整除n的数k,其中2≤k≤sqrt(n)

埃氏筛法,线性筛:基本思想:质数的倍数一定不是质数,每个合数只被它最大的非自身的因数筛掉

用合数=质数*合数的形式来筛数,保证质数是最小质因数

题目链接

#include<bits/stdc++.h>
using namespace std;
int f[10000002],p[10000002],cnt=0;
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=2;i<=n;i++)
	{
		if(f[i]==0) p[++cnt]=i;
		for(int j=1;j<=cnt&&i*p[j]<=n;j++)
		{
			f[i*p[j]]=1;
			if(i%p[j]==0) break;
//后面的p1[j]一定比当前p[j]大,所以后面的i*p1[j]可以换成i/p[j]*p1[j]与p[j]的乘积筛掉,i/p[j]*p1[j]要比i*p1[j]大且p[j]是i的因数
		}
	}
	int x;
	f[1]=1;
	for(int i=1;i<=m;i++){
		cin>>x;
		if(f[x]==1) cout<<"No"<<"\n";
		else cout<<"Yes"<<"\n";
	}
	return 0;
 } 

整除

性质

①若a|b且a|c,则有a|xb+yc

②若a|b且b|c,则a|c

③设m≠0,则ma|mb时,有a|b,反之亦然

④若a|b且b|a,则a=±b

特别地

对于任何整数a,总有1|a

对于任何整数a,a≠0,则a|0

数的整除特征

能被4、25整除的数:末两位数字组成的两位数能被4(25)整除的整数必能被4(25)整除

能被8,125整除的数:末三位数字组成的三位数能被8(125)整除的整数必能被8(125)整除

能被3,9整除的数:各个数位上数字之和能被3或9整除的整数必能被3或9整除

能被11整除的数:一个整数的奇数位数字之和与偶数位数字之和的差如果是11的倍数,则这个数就能被11整除.

能被7,11,13整除的数:一个三位以上的整数能否被7(11或13)整除,只须看这个数的末三位数字表示的三位数与末三位以前的数字组成的数的差(以大减小)能否被7(11或13)整除.

算数基本定理(惟一分解定理)及其推论

每个正整数都可以惟一地表示成质数的乘积。即有唯一的分解质因数方案:x=p1a1*p2a2……pnan

其中ai是正整数,pi是质数,且满足p1<p2<…pn。

x的约数个数: (a1+1)*(a2+1) …(an+1)

x的所有约数的和为:(1+p1+p12+…+p1a1)x…×(1+pn+pn2+…+pnan)

质因数分解

扫描2~sqrt(n)的每个质数d,若d能整除n,则从n中除掉所有的质因子d,同时累计除去的d的个数

若最终剩下的数不等于1,则它一定是一个质数,且为原数的质因子,我们也记入结果

结论:一个数n至多有一个大于sqrt(n)的质因子

证明;假设a,b是由n分解出的两个质因子,且a,b>sqrt(n),那么a×b是n的因子,

然而axb>n,所以a×b不可能是n的因子,所以原命题成立

时间复杂度为O(sqrt(n))

特别地,若n没有被任何2~sqrt(n)的数整除,则n是质数,无需分解。

因数分解

若d>=sqrt(n)是n的约数,则n/d≤ sqrt(n)也是n的约数

约数总是成对出现的(除了对于完全平方数, sqrt(n)会单独出现),

因此,只需要扫描d=1~ sqrt(n) ,尝试d能否整除n,若能整除,则n/d也是n的约数

时间复杂度为O( sqrt(n) )。

求1~n每个数的因数

对于每个数d,1~n中以d为约数的数就是d,2d,3d…floor(n/d)*d,时间复杂度为O(n+n/2+n/3+…+n/n)=O(nlogn)

最大公约数和最小公倍数

性质

①若a|m,b|m,则lcm(a,b)|m

②若d|a,d|b,则 d|gcd(a,b)

③设m,a,b是正整数,则lcm(ma,mb)= m*lcm(a,b)

④a×b=gcd(a,b)xlcm(a,b)

辗转相除法

O(logb)

int gcd(int a, int b)
{
return b == 0 ? a : gcd(b, a % b);
}

扩展欧几里得

求关于x,y的方程 ax + by = gcd(a,b) 的所有整数解。

一.求特解

a * x1 + b * y1 = g(a,b) 
b * x2 + (a%b) * y2 = g(b,a%b)

显然,两个等式右边就是欧几里徳的公式 那么得出 a * x1 + b * y1 = b * x2 + (a%b) * y2

其中a%b可以换成a-(a/b)*b ,式子变成了a * x1 + b * y1 = b * x2 + (a - (a / b) * b) * y2

因为要找x1 y1和x2 y2的关系,调整一下顺序,右边变成b * (x2 - (a / b) * y2) + a * y2

则等式变成了 a * x1 + b * y1 = a * y2 + b * (x2 - (a / b) * y2)

可得出下面两个等式:

x1 = y2(等式两边a的系数相同)

y1 = x2 - (a / b) * y2 (等式两边b的系数相同)

也就是说知道了方程b * x2 + (a%b) * y2 = g(b,a%b) 的解x2, y2,就可以得到方程a * x1 + b * y1 = g(a,b) 的解x1,y1了。

对于方程a * x + b * y = gcd(a,b),我们可以不断的往下变成b * x + (a % b) y = gcd(a,b)

按照欧几里徳的过程,b会变成0,即此时方程a * x + b * y = gcd(a,b) 因为b = 0,变成了a * x = gcd(a,b)

还是由欧几里徳算法得到,此时a就等于gcd(a,b),

所以得到由原方程往下推了不知道多少次的方程a * x = gcd(a,b)来说,得到一个解x = 1, y = 0。

现在得到了这个方程的解,利用上一个小问题的结论,就可以得出原方程a * x + b * y = gcd(a,b)的一个特解。可以通过不断递归调用求解。

二.用特解推出其他所有整数解

对于关于x,y的方程a * x + b * y = g 来说,让x增加b/g,让y减少a/g,等式两边还相等。

让x增加b/g,对于a * x这一项来说,增加了a * b / g,即增加了a,b的最小公倍数

同样,对于b * y这一项来说,y 减少 a/g,这一项减少了a * b / g,即增加了a,b的最小公倍数

可以看出,这两项一项增加了一个最小公倍数,一项减少了一个最小公倍数,加起来的和仍然等于g。

其实这种操作就是增加一个最小公倍数,减少一个最小公倍数,这样来改变x,y的值,来求出所有x,y的通解的。

三.

对于方程a * x + b * y = c 来说,它的解怎么求呢?

如果c % gcd(a,b) != 0,即c不是gcd的整数倍,则无解

如果c % gcd(a,b) == 0 且 c / gcd(a,b) = t

那么求出方程 a * x + b * y = gcd(a,b)的所有解x,y,将x,y乘上t,对应的x’,y’即是方程a * x + b * y = t * gcd(a,b)的解

互质

定义

若n个整数的最大公因数是1,则称这个n个整数互质。

posted @ 2020-09-19 15:13  zlq,  阅读(241)  评论(0编辑  收藏  举报