快速幂

方法一 :二进制求解法

假如求 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;
} 




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值