zoukankan      html  css  js  c++  java
  • 关于快速幂取模计算的详细解释

    首先对于幂和取模想必大家都不是很陌生,幂即一个数的多少次方,取模即取余运算:

    下面咱们进行一个数的幂取模运算的最容易想到的方式:

    a//底数

    b//幂指数

    c//取模数

    //算法一:
    int ans=1;
    for(int t=1;t<=b;t++)
    { 
        ans=ans*a;
    }
    return ans%c;
    

    时间复杂度为O(b),以上算法存在很大的一个问题在于多次求幂指数之后会超过整数类型的范围, 这是个很麻烦的问题

    但是我们在离散数学或者数论中曾接触到这样一个定理或者公式

    a^b mod c=(a mod c)^bmod c

    由此可以想到刚才的另一种求的算法

    //算法二:
    int ans=1;
    int a=a%c;
    for(int t=1;t<=b;t++)
    {
         ans=ans*a
    }
    return ans%c

    既然a的求幂过程中可以先转化成a%c,那我们不难想到在循环ans时也可以%c从而控制数的大小

    //算法三:
    int ans=1;
    int a=a%c;
    for(int t=1;t<=b;t++)
    {
      ans=(ans*a)%c;
    }
    return ans%c;

    数字超出整型范围的问题几本解决了 ,那我们能不能去降低O(b)的时间复杂度呢

    答案是肯定的:

    我们可以根据b来进行一定量的缩减:

    如果b是偶数,我们有如下公式

    a^bmodc=(a^2modc)^b^/^2modc

    同理奇数的公式也能相应的得到

    a^bmodc=[((a^2)^b^/^2modc)*a]modc

    这时,我们将a^2看做是一个变量k;

    于是有了下面的代码

    //算法4:
    int ans=1;
    int k;
    a=a%c;
    for(int t=1;t<=b/2;t++)
    {
        k=(a*a)%c;
      
        
    ans=(ans*k)%c;
    }
    if(b%2==1)
    return (ans*a%c)%c;
    else
    return ans%c; 

    此时我们的时间复杂度已经降到了O(b/2)

    那我们还能不能再提高一下呢

    答案依然是肯定的:

    这是反复循环利用了算法四的思想

    //算法5:
    //已经成为一个函数
    int quickpower(int x,int y,int z)
    {
    	int ans=1;
    	x=x%z;
    	while(y>0)
    	{
    		if(y%2==1)
    		{
    		  ans=(ans*x)%z;
    		}
    		y/=2;
    		x=x*x%z;
    	 }
    	 return ans;
    	 
    }

    时间复杂度为O(logb)一般情况基本不超时,

    还请大佬多多交流——————QQ656484427

  • 相关阅读:
    Linux 磁盘与文件系统管理
    mysql join
    iostat
    解决TIME_WAIT过多问题
    mysql 数据库性能追踪与分析
    CHECKPOINT
    DTRACE -MYSQL
    ORCLE INNODB 博客与 innodb_lru_scan_depth
    innodb 变量
    mysql博客
  • 原文地址:https://www.cnblogs.com/Staceyacm/p/10782112.html
Copyright © 2011-2022 走看看