• 欧几里得算法(及扩展)&&快速幂(二分+位运算)


      最近在二中苦逼地上课,天天听数论(当然听不懂)

      但是,简单的还是懂一点的

      1.欧几里得算法

      说得这么高级干什么,gcd入门一个月的人都会吧,还需要BB?

      证明可参照其他博客(不会),主要就是gcd(a,b)=gcd(b,a%b);

      特殊的,gcd(a,0)=gcd(0,a)=a;

      然后一行

    int gcd(int m,int n) { return n?gcd(n,m%n):m; }

      2.扩展欧几里得

      在班里天天看紫书,终于会打(背)了。

      专门对于形如 ax+by=d(a,b,d为常数,d=gcd(a,b)) 的不定方程求整数解

      证明可参照其他博客(不会),主要也是gcd(a,b)=gcd(b,a%b)(真有道理)

      

    void exgcd(int a,int b,int &x,int &y)
    {
        if (!b) { x=1; y=0; return; }
        int r=a%b,m=a/b;
        exgcd(b,r,y,x);
        y-=x*m;
    }

      然后这组解满足|x|+|y|最小

      其实记代码也是可以的啦。

      3.快速幂

      快速幂,一个入门一个月的人都会的算法,主流有二分和快速幂两个版本。

      原理不多说,一个是把a^n拆成两个相同的部分再递归求之。一个是不停增大初始部分然后得解。

      只不过一个是二分,一个是倍增了啦。

      <1>二分

    int quick_pow(int a,int n,int p) //a^n % p 
    {
        if (!n) return 1;
        int res=quick_pow(a,n/2,p);
        res=(long long) (res*res)%p;
        if (a%2) res=(long long) (res*a)%p;
        return res;
    }

      <2>位运算

    int Quick_pow(int a,int n,int p) //同上 
    {
        int res=1;
        while (n)
        {
            if (n&1) res=(long long) (res*a)%p;
            a=(long long) (a*a)%p;
            n=n>>1;
        }
        return res;
    }

      篇幅还算挺大,代码都是刚刚重打的,导致我看到的一道BZOJ的巨水题没时间打了。

      至于逆元,欧拉函数什么的。。。

      一脸蒙逼。

  • 相关阅读:
    找工作最近的一些收获
    nginx的开源项目
    找工作要看的
    各种排序算法的C实现
    解析递归程序和非递归程序
    Python在centos下的安装
    centos -bash-4.1$ 不显示用户名路径
    python easy_install centos 下安装过程和原理解析
    网络基础学习:
    MATLAB常用数据类型的转换
  • 原文地址:https://www.cnblogs.com/cjjsb/p/8039743.html
Copyright © 2020-2023  润新知