今天主要看了前三节的内容:整除,同余,最大公约数:
1、
对于整除一节的内容,主要是几条性质的应用,不过自己没有理解透彻,在看例题时也是费了好大功夫,也还没有完全明白。
2、
第二节的内容与上面一样,基本知识就那么几条性质,但是到了题目里就不是那么回事了,对于例题:指数取余,过去都是考虑最“简单‘的方法,暴力递推,而题解则提供了一种二进制分解的思想,着实不好理解。
3、
①:辗转相除法:核心原理GCD(x,y)=GCD(y,x%y),递归实现就好了。
②:二进制优化:
int fast_GCD(int x,int y)
{
int i,j;
if(x==0) return y;
if(y==0) return x;
for(i=0;0==(x&1);++i) x>>=1;
for(j=0;0==(y&1);++j) y>>=1;
if(j<i) i=j;
while(1)
{
if(x<y) x^=y,y^=x,x^=y;
if(0==(x-=y)) return y<<i;
while(0==(x&1)) x>>=1;
}
}
③:求最小公倍数:公式LCM(x,y)=x*y/GCD(x,y);
④:扩展欧几里得算法思想:
应用情形:求解:a*x+b*y=GCD(a,b):
思路:
已知a*x1+b*y1=GCD(a,b)=GCD(b,a%b)=b*x2+(a%b)*y2......(以此类推)
又因b*x2+(a%b)*y2=b*x2+(a-a/b*b)*y2=y2*a+b*(x2-(a/b)*y2),
所以可得:x1=y2; y1=x2-(a/b)*y2,即x1,y1由x2,y2得来,所以可以想到在递归退栈时逐层求解x、y;
最后,递归边界自然也就是求得最大公约数时,即b=0时。此时a*x1+b*y1=GCD(a,0)=a,所以x1=1,y1=0;
关键代码:
int extended_gcd(int a,int b,int &x,int &y)
{
int ans,t;
if (b==0) { x=1; y=0; return a; }
else { ans=extended_gcd(b,a%b,x,y); t=x; x=y; y=t-(a/b)*y;}//关键*
return ans;
}
⑤求解线性同余方程:
定理1: 对于方程 a*x+b*y=n;有整数解的充分必要条件是(n % GCD(a,b)==0)。
求解思路:
解a*x+b*y=GCD(a,b),得x1,y1;
。。。
所以有一解:x=x1*n/GCD(a,b),y=y1*n/GCD(a,b);
定理2:若(a,b)=1,且x0,y0为a*x+b*y=n的一组解,则该方程的任一解可表示为:x=x0+b*t,y=y0-a*t;且对任一整数t,皆成立。
如果求最小整数解,则有:t=b/(a,b),x=(x%t+t)%t。(具体为什么不理解。。。)
总结:很多证明难以理解,同时相应题目的解决也大都需要推导,且不容易考虑,总体来说,感觉今天的效果不是很好。