zoukankan      html  css  js  c++  java
  • 初等数论

    初等数论

    昨晚写到凌晨近一点,终于把自己目前会的数论知识做了下终结,最后发现原来只有这么点东西。。。路还好远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|bb|a <=> a=b;                         这个也比较显然。

     d=gcd(a,b);q=[a/b];qab的整数部分,比如 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;

    firstsecond 结合定理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,198都余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] qa/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   这里aiS的各位数字如 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可能几十几百万?哈哈,就用二进制咯,就是上面一个问题结合这个问题了!

    数论中还有其他的一些理论、慢慢再学勒、、、

     

     

  • 相关阅读:
    增加新分类daily——“每天学了啥?”
    gcc选项中的编译过程
    一个带路径复制的perl脚本
    git
    mysql explain 详解
    CentOS Python2.4升级到Python2.7
    mongoDb查询
    linux php 扩展
    php-redis 扩展安装
    redis Linux的安装方法
  • 原文地址:https://www.cnblogs.com/372465774y/p/2479953.html
Copyright © 2011-2022 走看看