初等数论
初等数论
昨晚写到凌晨近一点,终于把自己目前会的数论知识做了下终结,最后发现原来只有这么点东西。。。路还好远O(∩_∩)O哈!
一.求最大公约数:gcd(a,b)代表a,b的最大公约数,设为d;
(1)朴素算法:
暴力枚举咯.,先比较a,b大小,然后从1开始直到较小的那个数,算出最大可以被2数同时整除的数,即d;
(2)欧几里得算法:gcd(a,b)=gcd(b,a%b);递归求解;
在证明这个之前,首先得知道几个定理:
1.d=gcd(a,b)则d|ax+by; |代表的是整除;这个比较明显是正确的。
2.a|b且b|a <=> a=b; 这个也比较显然。
设d=gcd(a,b);q=[a/b];即q是a除b的整数部分,比如 5/2=2;
gcd(b,a%d)=gcd(b,a-q*b);由定理1可知d|a-q*b;
所以 d|gcd(b,a%b);即gcd(a,b)|gcd(b,a%b);……………….first;
设d=gcd(b,a%b); 同理可证gcd(b,a%b)|gcd(a,b);…..second;
由first和second 结合定理2可证得 gcd(a,b)=gcd(b,a%b);
(3)还有据说更快速的算法,这里简单介绍下:
a,b都为偶数 gcd(a,b)=gcd(a/2,b/2);
a,b都为奇数gcd(a,b)=gac(a-b,b);
a,b一奇一偶(假设b为偶数)gcd(a,b)=gcd(a,b/2);
这样递归下去
(以上算法都没说递归终止条件、嘿嘿、其实挺简单的,开动脑筋哈)
二同余求模,一介线性方程
先说下什么是同余,其实就是除以一个数,余数相同,算是个等价类吧;
比如 3,11,19除8都余3; 这类数可以表示为 3+8i (i=整数);
而同余求模方程就是 ax=b(mod n) 求解x;
我先把这个方程转化下 ax-b=ni (i=整数);
再移项 ax-in=b;这就成了二元一次方程了;
Ax+By=C;
这样的二元一次方程的解可能有无数个,只要找到一个就可以找到其他的了
假设 x0,y0是它的一个解,则通解为 x=x0-B1t, y=y0-A1t (t=整数)
这里的 A1=A/gcd(A,B), B1=B/gcd(A,B);
那么怎么求出这关键的解(有点像微分方程里说的特解O(∩_∩)O哈!)
这时,又是欧几里得哈,不过这次是欧几里得扩展算法了;
前面不是说过d=gcd(a,b)时有d|ax+by;
那么肯定有 x,y使得 d=ax+by 成立咯^_^;
那么怎么算出这个x,y呢;
d=gcd(a,b)=gcd(b,a%b); q=[a/b] q是a/b的整数部分;
所以 ax+by=bx’+(a-q*b)y’
整理得: ax+by=ay’+b(x’-qy’)
所以有 x=y’;
y=x’-qy’;
这样递归求下去递归的终止是 a=d,b=0,x=1,y=0;再倒退回来,求得需求的特解 x0,y0
这时,ax0+by0=d 这样特解就有了,什么?觉得c不一定等于d;
好吧,令 t=c/d;
那么 a*x*0t+b*y0*t=d*t=c;
这时的特解就是 t*x0,t*y0 ;
细心的你可能发现要是c/d不是整数怎么办,哈哈,那就说明无整数解了;
回到ax-in=b;
这里的 –I <=> y n <=> b b ó c;
照着上面的解法不就可以求出一个 X了吗?求出一个、其它的就太容易求了。
三:a^b求模问题:
1.首先看个简单的问题:333^111 除以 99余数是多少?
会编程的一般都说说:“So Easy!”
下面我来介绍下几种我知道的算法:%:取余数符号
(1).普遍的想法:求出一个333%99 把余数在乘333 然后 %99,如此反复进行111次,
电脑是运行很快,不过,当这个次方不是 111 而是 1亿,100亿,一万亿时,电脑CPU的负担挺大噢;
(2)定理 (a*c)%n=((a%n)*(b%n))%n;
那么我们是不是有更好的方法呢,
a^1%n
a^2%n
a^4%n
a^8%n
………..
这样,利用二进制、我们的速度就很明显的提升。
比如求 111^12 %33
我们只要求 111^1%n 111^2%n 111^4%n 111^8%n就可以了 111^12=(111^4*111^8)
而 111^2=(111^1)^2;
111^4=(111^2)^2;
…………..
二进制呀好强悍滴、、
我们把 12写成二进制模式即12=1100; 又比如 13=1101;
a^13=a^1*a^4*a^8;
这样a^b问题,就是把b看成二进制就好了;
2.最后讲数的各位和问题,
比如 1234 各位数和是10,不是一位数,再求 1+0=1;
再比如 87 8+7=15,不是一位数,再求 1+5=6;
这个问题也很简单、
把一个数求位数和、只要大于9,把得到的新数,再求,如此反复求;
我要介绍的是一种高效率的算法;
先证明个等式
a1a2a3a4…..an%9=(a1+a2+a3+…….+an)%9
证明:左边=(a1*10^n-1+a2*10^n-2+….an)%9
=(a1*(99..99+1)+a2*(99..99+1)+…..an)%9
=(a1+a2+a3+…..+an)%9;
设数S
S%9=(a1+a2+….an)%9 这里ai为S的各位数字如 123 a1=1,a2=2,a3=3;
设 S1=(a1+a2+….an)
S1%9=(a’1+a’2+….a’n)%9=S%9;
这样递推下去,可知最后的答案就是起始数S%9;
也就是说,告诉你一个数n,你直接n%9就是最后答案了,当然,如果余数是0,那么最后答案就是 9,这个很显然。
那么如果给的不是一般数呢,给的是 a^b a,b可能几十几百万?哈哈,就用二进制咯,就是上面一个问题结合这个问题了!
数论中还有其他的一些理论、慢慢再学勒、、、