一·、
快速幂:
例如:a^b
3 ^ 23 =3^ ( 2^0 + 2^1 + 2^2 + 2*4 )
个人理解:
指数23的二进制数: 1 0 1 1 1
当指数对应二进制位为 0 不执行运算
当指数对应二进制位执行运算
注意快速幂爆 int 的问题
#include <bits/stdc++.h>
using namespace std;
long long Qmult(long long a,long long b,long long c)
{//快速幂,a为底,b为指数,c为取余的数
long long ans=1;
while(b!=0)
{
if(b&1) //对应指数的二进制位为1时,执行运算;对应二进制位为0时,不执行
ans=ans*a%c;
a=a*a%c; //更新底数,实现累乘
b>>=1; //丢掉指数的二进制的低位
}
return ans; //返回结果
}
int main()
{
int t;
cin>>t;
while(t--)
{
int a,n,b,result;
cin>>a>>n>>b;
result=Qmult(a,n,b);
cout<<result<<endl;
}
}
#include <bits/stdc++.h>
using namespace std;
long long Q_mull(long long A,long long B,long long mod) //快速乘
{
long long ans=0;
long long res=A;
while(B)
{
if(B&1)
ans=(res+ans)%mod;
res=(res+res)%mod;
B>>=1;
}
return ans;
}
long long Qmult(long long a,long long b,long long c) //快速幂
{
long long ans=1;
while(b)
{
if(b&1)
ans=Q_mull(ans,a,c);
a=Q_mull(a,a,c);
b>>=1;
}
return ans;
}
int main()
{
int t;
cin>>t;
while(t--)
{
long long a,b,p,result;
cin>>a>>b>>p;
result=Qmult(a,b,p);
cout<<result<<endl;
}
return 0;
}
快速乘法:
当两个数相称可能超过long long 范围的时候用,因为在加法运算的时候不会超,而且可以直接取模,这样就会保证数据超不了了。
#include<iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef long long LL;
LL fast_multi(LL m, LL n, LL mod)//快速乘法
{
LL ans = 0;//注意初始化是0,不是1
while (n)
{
if (n & 1)
ans += m;
m = (m + m) % mod;//和快速幂一样,只不过这里是加
m %= mod;//取模,不要超出范围
ans %= mod;
n >>= 1;
}
return ans;
}
LL fast_pow(LL a, LL n, LL mod)//快速幂
{
LL ans = 1;
while (n)
{
if (n & 1)
ans = fast_multi(ans, a, mod);//不能直接乘
a = fast_multi(a, a, mod);
ans %= mod;
a %= mod;
n >>= 1;
}
return ans;
}
int main()
{
LL n, p;
while (~scanf("%I64d %I64d", &n, &p))
{
if (n == 1)//特判一下
{
printf("%I64d\n", 1 % p);
continue;
}
printf("%I64d\n", (fast_pow(2, n, p) - 2 + p) % p);//这一步注意,不要为负数
}
return 0;
}