快速幂模板
算法思想
以下以求a的b次方来介绍[1]
把b转换成二进制数。
该二进制数第i位的权为
例如 a^11 = a^(2³×1 + 2²×0 + 2¹×1 + 2º×1)
11的二进制是1011
11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1
因此,我们将a¹¹转化为算 a¹¹ = a²^º×a²^¹×a²^³
代码
int qpow(int a,int b)
{
int r=1,base=a;
while(b!=0)
{
if(b&1)
r*=base;
base*=base;
b>>=1;
}
return r;
}
费马小定理
费马小定理(Fermat’s little theorem)是数论中的一个重要定理,在1636年提出,其内容为: 假如p是质数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p),即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。
HDU4704
求sum(s) = 2^(n-1)
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
const long long MOD = 1e9+7 ;
const long long N = 1e5+5;
using namespace std;
char str[N];
inline long long qpow(long long x,long long y,long long MOD)
{
long long ans=1,tem=x;
while(y)
{
if(y&1)ans = (ans*tem)%MOD;
tem = (tem*tem)%MOD;
y>>=1;
}return ans ;
}
inline long long getPow()
{
long long value = 0;
for(int i=0;str[i]!='\0';i++)
{
value =( value*10 + (str[i]-'0') ) % (MOD-1);
}return value ;
}
int main()
{
while(scanf("%s",str)==1)
{
long long pow = getPow();
printf("%I64d\n",qpow(2,pow-1,MOD));
}
}