一.快速幂
快速幂一般用于求 A^B%C 的时候,当B很大的时侯常需要取模。快速幂可以优化时间复杂度。
typedef long long LL;
LL fun(LL x,LL n,LL c)
{
LL res=1;
while(n>0)
{
if(n & 1)
res=(res*x)%c;
x=(x*x)%c;
n>>= 1;
}
return res;
}
二.快速乘
快速幂一般用于求 A*B%C,A*B超出long long int的时候,而且在计算机中加法往往比乘法快,可以优化时间复杂度。
快速乘是将后面的乘数转化成二进制形式,例如23*25可转化成23*11001(25的二进制数)=23*2^4+23*2^3+23*2^0
typedef long long LL;
LL fun(LL x,LL n,LL c)
{
LL res=1;
while(n>0)
{
if(n & 1)
res=(res+x)%c;
x=(x+x)%c;
n>>= 1;
}
return res;
}
三.快速幂和快速乘的结合应用
http://acm.fzu.edu.cn/problem.php?pid=1752
问题1752 A ^ B mod C.
接受:1143提交:5227
时间限制:1000毫秒内存限制:32768 KB
问题描述
给定A,B,C,您应该快速计算A ^ B mod C的结果(1 <= A,B,C <2 ^ 63)。
输入
有多个测试用例。每个测试用例中,有一行包含三个整数A,B和C,由单个空格分隔。
产量
对于每个测试用例,输出一个整数,表示A ^ B mod C的结果。
样本输入
3 2 4 2 10 1000
样本输出
1 24
这道题就是需要结合用。
代码来自大佬博客https://blog.csdn.net/Dog_dream/article/details/82467824
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
ll mulit(ll a,ll b,ll c)//快速乘
{
ll ans=0;
a%=c;
while(b)
{
if(b&1)
{
ans+=a;
if(ans>c){ans-=c;}//大于减c
}
a<<=1;
if(a>=c)a-=c;
b>>=1;
}
return ans;
}
ll quick(ll a,ll b,ll c)//求阶乘
{
ll ans=1;
while(b)
{
if(b&1){ans=mulit(ans,a,c);}
a=mulit(a,a,c);
b>>=1;
}
return ans;
}
int main()
{
ll a,b,c;
while(~scanf("%I64d%I64d%I64d",&a,&b,&c))
{
printf("%I64d\n",quick(a,b,c));
}
return 0;
}