• 关于快速幂取模计算的详细解释


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

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

    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

  • 相关阅读:
    Cannot retrieve repository metadata (repomd.xml) for repository: fedora. P、、、
    Fedora 学习总结
    Gnome 高级配置
    [置顶]Fedora 13,14,15安装LAMP
    如何删去Fedora下应用程序菜单中的多余程序启动器?
    运用Telnet在windowsxp中与虚拟机中fedora14互联
    运用Telnet在Windows xp中与虚拟机中fedora14互连
    netstat 的应用
    在 fedora14 下升级 firefox 到 firefox4 的两种方案
    windows 中相关CMD应用
  • 原文地址:https://www.cnblogs.com/Staceyacm/p/10782112.html
Copyright © 2020-2023  润新知