快速幂

本蒟蒻学到了一种可以快速求a^b%c的算法,具体题目:洛谷P1226

传送门:https://www.luogu.org/problemnew/show/P1226

看到这道题,首先想到的暴力方法肯定是直接开循环,暴力乘积,代码如下:

long long ans = 1;    
for(int i = 1;i<=b;i++)    
{    
ans = ans * a;    
}    
ans = ans % c;

然而根据本道题的数据,这样是一个点都过不了的:

这就要采用一种算法——快速幂:

快速幂是一种神奇的思想,属于倍增,基本公式有两个:

第一个:(当n为偶数时)2^n=(2^2)^(n/2)=4^(n/2)

第二个:(当n为奇数时)2^n=((2^2)^(n/2))*2=(4^(n/2))*2

好了,了解了这些,下面先贴上本道题的代码(有点丑)

#include<stdio.h>
int main()
{
	long long a,aa,b,c,ans=1,bb;
	scanf("%lld%lld%lld",&a,&b,&c);
	aa=a;
	a%=c;
	bb=b;
    while(b>0)  
    {  
     if(b%2==1)ans=(ans*a)%c;  
     b=b/2;  
     a=(a%c)*(a%c)%c;  
    }
    printf("%lld^%lld mod %lld=%lld",aa,bb,c,ans%c);
    return 0;
}	long long a,aa,b,c,ans=1,bb;
	scanf("%lld%lld%lld",&a,&b,&c);
	aa=a;
	a%=c;
	bb=b;
    while(b>0)  
    {  
     if(b%2==1)ans=(ans*a)%c;  
     b=b/2;  
     a=(a%c)*(a%c)%c;  
    }
    printf("%lld^%lld mod %lld=%lld",aa,bb,c,ans%c);
    return 0;
}

建议大家用我接下来给的样例自己调试一下看一下原理,如果看不出来什么,也可以边调程序边看我的分析(看不懂的一定要验算验算,自己写一写,或多看几遍),在看完我的分析后,想要加深印象的可以再点开文章顶部的链接,看洛谷上的样例,自己再推一推。

            输入:5 10 9            输出:4

              在这里只解释前两次的while循环:

               当b=10,a=5时,b%2=0,所以此时运用上面的基本公式1可得5^10=25^5。 所以我们将b/=2,用a的平方更新a。

               此时b=5,a=25,b%2=1,所以运用基本公式2,可得25^5=(625^2)*25。所以我们的ans*=a,再b/=2,a=a*a.

               以此类推……

好了,快速幂就讲解到这,如有大佬发现错误,希望及时留言督促我更正。

有一道练习题,NOIP2013提高组T1

传送门:https://www.luogu.org/problemnew/show/P1965

这是一道模板题!

代码如下:

#include<stdio.h>
int n,m,k,x,tot=10,ans=1;
void ksm()
{
	while(k)
	{
	 if(k%2==1)ans=ans*tot%n;
	 tot=tot*tot%n;
	 k/=2;
	}
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&k,&x);
	ksm();
	printf("%d",(x%n+m%n*ans%n)%n);
	return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值