快速幂||矩阵快速幂


对应习题:poj3070 ,poj 3233

快速幂:

点击打开链接

#include<iostream>
using namespace std;
#define LL long long
#define MAX 99999999999
LL  fastPower(LL num,LL n){
    LL ret=1;
    while(n){
        if(n&1)
            ret=(ret*num)%MAX;
        num=(num*num)%MAX;
        n>>=1;
    }
    return ret;
}
int main()
{
    LL num,n;
    cout<<MAX<<endl;
    while(cin>>num>>n){
        cout<<fastPower(num,n)<<endl;
    }
}
矩阵快速幂

点击打开链接

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream> 
using namespace std;

int N;

struct matrix
{
       int a[3][3];
}origin,res;


matrix multiply(matrix x,matrix y)
{
       matrix temp;
       memset(temp.a,0,sizeof(temp.a));
       for(int i=0;i<3;i++)
       {
               for(int j=0;j<3;j++)
               {
                       for(int k=0;k<3;k++)
                       {
                               temp.a[i][j]+=x.a[i][k]*y.a[k][j];
                       }
               }
       }
       return temp;
}

void init()
{
     printf("随机数组如下:\n");
     for(int i=0;i<3;i++)
     {
             for(int j=0;j<3;j++)
             {
                     origin.a[i][j]=rand()%10;
                     printf("%8d",origin.a[i][j]);
             }
             printf("\n");
     }
     printf("\n");
     memset(res.a,0,sizeof(res.a));
     res.a[0][0]=res.a[1][1]=res.a[2][2]=1;                  //将res.a初始化为单位矩阵 
}

void calc(int n)
{
     while(n)
     {
             if(n&1)
                    res=multiply(res,origin);
             n>>=1;
             origin=multiply(origin,origin);
     }
     printf("%d次幂结果如下:\n",n);
     for(int i=0;i<3;i++)
     {
             for(int j=0;j<3;j++)
                     printf("%8d",res.a[i][j]);
             printf("\n");
     }
     printf("\n");
}
int main()
{
    while(cin>>N)
    {
            init();
            calc(N);
    }
    return 0;
}


#include<iostream>
#include <cstring>
#include <cstdio>
#define MAX 40
using namespace std;
#define MOD 10000
struct Mat
{
    int a[MAX][MAX];
    int m,n;
    Mat(int _m,int _n):m(_m),n(_n){
        memset(a,0,sizeof(a));
    }
    void sim(){
        for(int i=0;i<m&&i<n;i++)
            a[i][i]=1;
    }
    Mat operator *(Mat other){
        Mat c(m,other.n);
        for(int i=0;i<n;++i)  {
            for(int k=0;k<n;++k){
                if(a[i][k]){
                    for(int j=0;j<n;++j){
                        c.a[i][j]+=a[i][k]*other.a[k][j];
                    if(c.a[i][j]>=MOD)
                        c.a[i][j]%=MOD;
                    }
                }
            }
        }
        return c;
    }
    Mat operator^(int k){
        if(k==1)
            return *this;
        Mat e(m,n);
        e.sim();
        if(k==0) return e;
        Mat p=*this;
        while(k)
        {
            if(k&1)e=p*e;
            p=p*p;
            k>>=1;
        }
        return e;
    }
};

int  main()
{
    Mat d(2,2);
    d.a[1][1]=0;
    d.a[1][0]=d.a[0][1]=d.a[0][0]=1;
    int k;
    while(~scanf("%d",&k)){
        if(k==-1)
            break;
        Mat ans=d^k;
        printf("%d\n",ans.a[0][1]%MOD);

    }
}
#include<iostream>
#include <cstring>
#include <cstdio>
#define MAX 40
using namespace std;
int mod=100;
struct Mat
{
    int a[MAX][MAX];
    int m,n;
    Mat(){m=n=0;}
    Mat(int _m,int _n):m(_m),n(_n){
        memset(a,0,sizeof(a));
    }
    void sim(){
        for(int i=0;i<m&&i<n;i++)
            a[i][i]=1;
    }
    Mat operator *(Mat other){
        Mat c(m,other.n);
        for(int i=0;i<n;++i)  {
            for(int k=0;k<n;++k){
                if(a[i][k]){
                    for(int j=0;j<n;++j){
                        c.a[i][j]+=a[i][k]*other.a[k][j];
                    if(c.a[i][j]>=mod)
                        c.a[i][j]%=mod;
                    }
                }
            }
        }
        return c;
    }
    Mat operator^(int k){
        if(k==1)
            return *this;
        Mat e(m,n);
        e.sim();
        if(k==0) return e;
        Mat p=*this;
        while(k)
        {
            if(k&1)e=p*e;
            p=p*p;
            k>>=1;
        }
        return e;
    }
    Mat operator+(Mat other){
        Mat c(m,n);
        for(int i=0;i<m&i<other.m;i++)
            for(int j=0;j<n&&j<other.n;j++){
                 c.a[i][j]=a[i][j]+other.a[i][j];
                 if(c.a[i][j]>=mod)
                    c.a[i][j]%=mod;
            }

        return c;
    }
    friend istream&operator>>(istream&is,Mat& mat){
        for(int i=0;i<mat.m;i++)
            for(int j=0;j<mat.n;j++){
                is>>mat.a[i][j];
                if(mat.a[i][j]>=mod)
                    mat.a[i][j]%=mod;
            }
        return is;
    }

    friend ostream& operator<<(ostream& os,Mat mat){
        for(int i=0;i<mat.m;i++){
            for(int j=0;j<mat.n;j++){
                os<<mat.a[i][j];
                if(j!=mat.n-1)
                    os<<" ";
            }

            os<<endl;
        }
        return os;
    }
};
Mat mat;
Mat sum(int k){

    if(k==1)
        return mat;
    if(k&1)
        return sum(k-1)+mat^k;
    else {
       Mat s=sum(k>>1);
       return s+s*(mat^(k>>1));
    }
}
int  main()
{
   int n,k;
   while(cin>>n>>k>>mod){
        mat=Mat(n,n);
        cin>>mat;
        mat=sum(k);
        cout<<mat;
   }
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值