本蒟蒻学到了一种可以快速求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;
}