主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法...

36
数数 数数数数 数数数数数 数数数数数数数数数数数数 数数数数数数数数 数数数数数数数数 数数数数数数

description

数论. 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组. 整除与约数. 对于整数 d 和 a ,如果存在整数 k 使得 a=k*d ,我们就说 d 能整除 a ,记为 d|a (读作 d 整除 a ) 例如,因为 24=3*8 所以 3 能整除 24 ,记为 3|24 如果 d|a ,并且 d>0 ,则称 d 是 a 的 约数 。 例如, 24 的约数有 1 、 2 、 3 、 4 、 6 、 8 、 12 、 24. 每个整数 a 都可以被其 平凡约数 1 和 a 整除, - PowerPoint PPT Presentation

Transcript of 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法...

Page 1: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

数论主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

Page 2: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

整除与约数 对于整数 d 和 a ,如果存在整数 k 使得 a=k*d ,

我们就说 d 能整除 a ,记为 d|a (读作 d 整除 a)

例如,因为 24=3*8 所以 3 能整除 24 ,记为 3|24 如果 d|a ,并且 d>0 ,则称 d 是 a 的约数。

例如, 24 的约数有 1 、 2 、 3 、 4 、 6 、 8 、 12 、 24.

每个整数 a 都可以被其平凡约数 1 和 a 整除, a 的非平凡约数也称为 a 的因子。

Page 3: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

素数与合数

对于某个大于 1 的整数 a ,如果它仅有平凡约数 1 和 a 则称 a 是素数(或质数)。否则称 a 是合数。

素数有 2 , 3 , 5 , 7 , 11 , 13 , 17 ,19 , 23 , 29 , ···

素数有无穷多个

Page 4: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

素数的应用 唯一素因子分解定理:合数 a 仅能以一种方式,

写成如下的乘积形式: a=p1e1p2

e2…prer

其中 pi 为素数, p1<p2<…<pr ,且 ei 为正整数 如果正整数 n 分解质因子的结果为 n=p1

e1p2e2…p

rer ,

则 n 的约数个数为 : (e1+1)*(e2+1)*…*(er+1) 。所有约数之和为: (1+p1+p1

2+…+p1e1)*(1+p2+p2

2

+…+p2e2) *…*(1+pr+pr

2+…+prer)

Page 5: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

素数的判定

对于大于 1 的正整数 a ,如果 a 具有小于或等于 sqrt ( a )的素因子,则 a 为合数,否则 a 为素数。

因此,可用区间 [2,sqrt(a)] 内的数去试除a ,只要有一个数能整除 a ,则 a 为合数,否则 a 为素数。这种判断素数的方法就是试除法。

复杂度 O(sqrt(n)).

Page 6: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

试除法

IsPrime(a)for(i=2;i*i<=a;i++)

if(a%i==0) return a 为合数

return a 为素数

Page 7: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

筛法求素数 如果要判断一个区间内的数是否为素数,也可用

筛法求素数。 算法思想:

1) 将所有候选数 2~n 放入筛中 ; 2) 找出筛中最小数 P , P 一定为素数。 3) 宣布 P 为素数,并将 P 的所有倍数从筛中筛去 ; 4) 重复 2) 至 3) 直到筛空 .

其实,当 P>sqrt(n) 时筛中剩下的数就已经都是素数了。

Page 8: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

筛法求素数// 用数组 prime[MAXN] 记录是否为素数;//prime[i] 为 0 表示 i 为素数,否则为合数

int prime[MAXN]={0};for(i=2;i*i<=n;i++)

{if(prime[i]==0){

for(j=i+i;j<=n;j+=i)prime[j]=1;

}}

Page 9: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

因式分解 tn=n; for(i=2;i*i<=n;i++)// 试除 2~sqrt(n) if(tn%i==0){// 如果能被 i 整除 p[++cnt]=i;// 保存底数 e[cnt]=0;// 保存指数 while(tn%i==0){// 计算指数 e[cnt]++; tn/=i; } } } if(tn>1){// 存在大于 sqrt(n) 的素因子 p[++cnt]=tn; e[cnt]=1; }

Page 10: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

例题一: Goldbach's Conjecture(TOJ1171)

题目描述: 对于输入的偶数 n(6≤n<1000000), 是否

可以表示为两个奇素数之和。如果可以表示,输出表达式,否则输出 "Goldbach's conjecture is wrong."

Page 11: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

例题一: Goldbach's Conjecture(TOJ1171)

Sample Input 8 20 42 0

Sample Output 8 = 3 + 5 20 = 3 + 17 42 = 5 + 37

Page 12: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

例题一: Goldbach's Conjecture(TOJ1171)

假设两个奇素数中较小的一个为 a , 让 a 从 2 取到 n/2 ,如果 a 取到某个值时

a 与 n-a 都为素数,则此时的 a 与 n-a 的值便是所求。

如果最终找不到满足条件的 a 则无解,输出“ Goldbach‘s conjecture is wrong.” 即可。

因此可以用筛法预先计算出 2~1000000内的素数,然后判断即可

Page 13: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

最大公约数与最小公倍数 d 是 a 的约数并且也是 b 的约数,则 d 是 a

与 b 的公约数。 两个不同时为 0 的整数 a 和 b 的最大公约数

表示为 gcd(a, b) 。 如果 d 既能被 a 整除也能被 b 整除,则 d

是 a 与 b 的公倍数, a 与 b 公倍数中最小的叫 a 与 b 的最小公倍数,表示为 lcm(a,b).

gcd(a,b)*lcm(a,b)=a*b 最大公约数为 1 的两个数互质

Page 14: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

最大公约数的求法 GCD 递归定理:

对任意非负整数 a 和任意正整数 b ,有gcd(a, b) = gcd(b, a mod b) 。

Page 15: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

最大公约数的求法 欧几里德算法(也叫辗转相除法):

EUCLID(a, b) if b = 0 then return a else return EUCLID(b, a % b)例如 :

gcd(18,24)=gcd(24,18)=gcd(18,6)=gcd(6,0) =6

算法复杂度 O(lg(b))

Page 16: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

欧几里德算法

int gcd(int a,int b){

if(b==0)return a;

return gcd(b,a%b);}

Page 17: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

扩展欧几里德算法

通过欧几里德算法我们不仅能求出 a 与 b的最大公约数,

还可以改写欧几里德算法,求出整数 x 和y 使得 gcd(a,b)=ax+by

Page 18: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

扩展欧几里德算法 设 a’=a mod b= a-b*floor(a/b);

假如我们通过递归得到了 gcd(b,a’)=b*x’+a’*y’的 x’,y’的值,则因为 gcd(a,b)=gcd(b,a mod b )=gcd(b,a’);有等式 gcd(a,b)=b*x’+a’*y’

代入 a’可以得到 gcd(a,b)=b*x’+(a-b*floor(a/b))*y’即 gcd(a,b)=a*y’+b*(x’-floor(a/b)*y’)所以只要将 gcd(a,b)=a*x+b*y中的 x换为 y’,y 换为x’-floor(a/b)*y’即可,

同时我们有递归的基本情形 gcd(a,0)=a*1+b*0.

Page 19: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

扩展欧几里德算法 1. EXTENDED-EUCLID(a, b) 2.if b = 0 3. then return (a, 1, 0) 4.(d’,x’,y’) ←EXTENDED-EUCLID(b, a%b) 5.(d, x, y) ←(d’, y’, x’–(a/b) * y’) 6.return (d, x, y)

Page 20: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

扩展欧几里德算法 int ext_gcd(int a,int b,int &x,int &y) { if(b==0) { x=1; y=0; return a; } int d=ext_gcd(b,a%b,x,y); int tx=x; x=y; y=tx-a/b*y; return d; }

Page 21: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

例题二: A famous math puzzle (TOJ2219)  

题目描述: 有 n 个壶,和无穷多的水.每次我们只能: 1.把其中一个壶灌满. 2.把其中一个壶倒空. 3.把一个壶中的水倒入另一个壶中,直到一个壶为空或者另一个壶已经满了为止.

给定一个体积W,问能否经过若干次倒水后使得最终有一个壶中只剩下W升水?如果能,输出”YES”, 否则输出” NO”

Page 22: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

例题二: A famous math puzzle (TOJ2219)  

Sample Input: 2 4 5 6 2 10 65 39 2 12 4 8 3 9 10 35 14 0 0

Sample Output: YES NO NO YES

Page 23: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

例题二: A famous math puzzle (TOJ2219)  

要使 n 个水壶能倒出 w体积的水,则必须符合以下两个条件:

1.至少有一个水壶的容量大于或等于 w. 2.假设 p 是 n 个水壶容量的最大公约数,那么 w必须 p 的倍数.

Page 24: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

例题二: A famous math puzzle (TOJ2219)  

假设 n 个水壶的容量分别为 C1,C2,C3…..Cn. 必要性:不管执行三种操作的那一种,壶中所含

的水一定是P的整数倍. 充分性:由欧几里德算法扩展可知,必然存在整

数 A1,A2,A3…..An, 使得  A1*C1+A2*C2+A3*C3+…+An*Cn=W. 如果 Ai 是正数,我们就用第 i 个壶从水源中取 Ai次水;如果 Ai 为负数,我们就把第 i 个壶倒空 Ai次,这样最后必会剩下W升水

Page 25: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

同余的概念

两个整数 a , b ,若它们除以整数 m 所得的余数相等,则称 a , b 对于模 m 同余记作 a ≡ b (mod m) 读作 a 与 b关于模m 同余。

Page 26: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

模的相关运算

(x+y)mod n=((x mod n)+(y mod n)) mod n

(x-y)mod n=((x mod n) - (y mod n)) mod n

x*y mod n = (x mod n)*(y mod n) mod n

Page 27: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

乘法逆元

若 ax≡1(mod n) 则称 a 对 n 的乘法逆元为 x , 记为 a-1(mod n)

设 b 为整数,如果 a 对 n 的乘法逆元为 x ,则b/a(mod n) =b*a-1 (mod n)

乘法逆元并不总存在,如 2x ≡ 1(mod 4).

Page 28: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

模线性方程 ax≡b(mod n) 为模线性方程, x 为未知数。 定理一:设 d=gcd(a, n) ,假定对整数 x’和y’,有 d=ax’+ny’。如果 d|b ,则方程 ax ≡ b(mod n) 有一个解的值为 x0 ,满足 x0=x’(b/d)mod n 。

定理二:假设方程 ax ≡ b(mod n) 有解(即有 d|b ,其中 d=gcd(a, n) ), x0 是该方程的任意一个解,则该方程对模 n恰有 d 个不同的解,分别为: xi=x0+i(n/d)(i = 1, 2, …, d-1) 。

Page 29: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

模线性方程的解法

1. SOLVE(a, b, n)2. (d,x’,y’) ←EXTENDED-EUCLID(a, n)3. if (d | b)4. then x0 ←x’(b/d)mod n5. for i ←0 to d-16. print(x0 + i(n / d)) mod n7.else print “ 无解”

Page 30: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

例题三: C Looooops (TOJ 2297)

题意描述:对于以下循环语句 for (variable = A; variable != B; variable+= C)

statement; 如果给定 A , B, C , k 的值, statement语句会执行多少次,假设其中所有变量都是 k位无符号整数类型,( 1 ≤k ≤32 )

如果此循环语句不会停止,输出” FOREVER” ,否则输出执行次数。

输入数据以 4 个 0 结束

Page 31: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

例题三: C Looooops (TOJ 2297)

Sample Input 3 3 2 16 3 7 2 16 7 3 2 16 3 4 2 16 0 0 0 0

Sample Output 0 2 32766 FOREVER

Page 32: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

例题三: C Looooops (TOJ 2297)

因为所有变量都是 k位无符号整数类型,当语句执行 X次后,变量 variable 的值变为

(A+C*X)(mod 2k)所以当

(A+C*X)(mod 2k)=B(mod 2k) 时循环停止,化简得 C*X≡(B-A)(mod 2k),解模线性方程求出所有 X ,如果有解,输出

最小的正整数解即可,否则输出“ FOREVER” 。

Page 33: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

模线性方程组

例子:(孙子算经)今有物不知其数。三三数之余二;五五数之余三;七七数之余二。问物几何?答曰:二十三。23≡2*70+3*21+2*15(mod 105)口诀:三人同行七十稀,五树梅花廿一枝,

七子团圆月正半,除百零五便得知。

Page 34: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

模线性方程组中国剩余定理:设自然数 n1,n2,…nr 两两互素,并记 N=n1n2…nr ,则同余方

程组

在模 N 同余的意义下有唯一解。X≡(a1c1+a2c2+…+arcr)(mod N)其中, ci=mi*(mi

-1mod ni),mi=N/ni

因为 Xmod ni=(a1m1m1-1+a2m2m2

-1+…+armrmr-1) mod ni

=(aimimi-1 )mod ni=aimod ni

)(mod

)(mod

)(mod

22

11

rr naX

naX

naX

Page 35: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

中国剩余定理 // 计算 X mod ni = ai (i = 1...k) int China(int k, int a[], int n[]){ ans = 0; N = 1 for(i = 0; i < k; i++){ N *= n[i]; } for(i = 0; i < k; i++){ m = N / n[i]; ext_gcd(m % n[i] , n[i] ,x, y); ans += a[i] * m * (x % n[i]); ans %= N; } if(ans<=0)ans+=N; return ans; }

Page 36: 主要内容: 筛法求素数 欧几里德算法求最大公约数 扩展欧几里德算法 模线性方程的解法 模线性方程组

相关题目 发信人 : agrael (+3), 信区 : ACM 标 题 : ACM-ICPC讲座 数论:相关题目: http://acm.tju.edu.cn/toj/showp1171.html http://acm.tju.edu.cn/toj/showp1038.html http://acm.tju.edu.cn/toj/showp2901.html http://acm.tju.edu.cn/toj/showp3076.html http://acm.tju.edu.cn/toj/showp3043.html http://acm.tju.edu.cn/toj/showp2339.html http://acm.tju.edu.cn/toj/showp2010.html http://acm.tju.edu.cn/toj/showp1296.html http://acm.tju.edu.cn/toj/showp2297.html 扩展欧几里德算法 http://acm.tju.edu.cn/toj/showp2219.html 扩展欧几里德算法 http://acm.tju.edu.cn/toj/showp2869.html 扩展欧几里德算法 http://acm.tju.edu.cn/toj/showp1089.html 求所有约数和 http://acm.tju.edu.cn/toj/showp1162.html 模线性方程组