方法一 :二进制求解法
假如求 x ^ n 次方,我们可以把 n 表示为 2^k1 + 2k2 + 2^k3....,(其实就是二进制表示数的原理)
那么 x^n = x^2^k1 * x^2^k2 * x^2^k3......那么就可以利用二进制来加快计算速度了。
假如 x^22 , 22转化为二进制为 10110, 即 x^22 = x^16 * x^4 * x^2;
#include<iostream>
using namespace std;
long long quickmod(long long a,long long b,long long m)
{
long long ans = 1;
while(b)//用一个循环从右到左遍历b的所有二进制位
{
if(b&1)//这是按二进制表示进行“与”运算的;判断此时b[i]的二进制位是否为1
ans = (ans*a)%m;//乘到结果上,这里a是a^(2^i)%m
b/=2; //b的所有二进制向右平移一位
a = a*a%m;
}
return ans;
}
int main()
{
long long ans, a,b,m;
cin>>a>>b>>m;
ans=quickmod(a,b,m);
cout<<ans<<endl;
return 0;
}
方法二:二分思想,分奇偶讨论
a^b%c,当b比较大时可将其分解
当b为偶数时,a^b%c=(a^(b/2)*a^(b/2))%c;当b为奇数时,a^b%c=(a^(b/2)*a^(b/2)*a)%c
#include<iostream>
using namespace std;
long long ans;
void power(long long a,long long b,long long m)
{
if(b==0)
{
ans=1;
return;
}
if(b==1)
{
ans=a%m;
return;
}
power(a,b>>1,m); //二分 ,每次将n的二进制普遍向右移动一位,相当于b=b/2;
ans=((ans%m)*(ans%m))%m;
if(b&1) //n为奇数时需要多乘一次 ,二进制末尾是0则是偶数,1则是奇数
{
ans=((ans%m)*(a%m))%m;
return;
}
return;
}
int main()
{
long long a,b,m;
while(cin>>a>>b>>m)
{
power(a,b,m);
cout<<ans<<endl;
}
return 0;
}
快速幂——矩阵运算
求解矩阵的n次幂
#include<iostream>
#include<string.h>
using namespace std;
int n,N;
struct matrix//用结构体封装一个二维数组!!!
{
int a[100][100];
}origin,res;//res.a存储结果 ,origin.a是需要运算的矩阵 ,n是次幂数 ,N是矩阵的行列数
matrix multiply(matrix x,matrix y)//矩阵相乘函数
{
matrix temp;
memset(temp.a,0,sizeof(temp.a));
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
for(int k=0;k<N;k++)
{
temp.a[i][j]+=x.a[i][k]*y.a[k][j];
}
}
}
return temp;
}
void calc(int n)
{
memset(res.a,0,sizeof(res.a));
for(int i=0;i<N;i++)
res.a[i][i]=1; //将res.a初始化为单位矩阵
while(n)
{
if(n&1)
res=multiply(res,origin);
n>>=1;
origin=multiply(origin,origin);
}
}
int main()
{
cin>>N;//矩阵的行列数
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
cin>>origin.a[i][j];
cin>>n;//输入运算的次幂数
calc(n);
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
cout<<res.a[i][j]<<" ";
cout<<endl;
}
return 0;
}