zoukankan      html  css  js  c++  java
  • 【数论】 快速幂&&矩阵快速幂

    首先复习快速幂

    #include<bits/stdc++.h>
    using namespace std;
    long long power(long long a,long long b,long long k)
    {
        long long ans=1,base=a;
        while (b>0)
        {
            if(b&1)    
            {
                ans*=base;
                ans%=k;
            }
            base*=base;
            base%=k;
            b>>=1;
        }
        return ans;
    }
    int main()
    {
        long long b,p,k;
        cin>>b>>p>>k;
        cout<<b<<'^'<<p<<" mod "<<k<<"="<<(power(b,p,k) % k);
        return 0;
    } 

    我居然不DEFINE LL?可以看到上面的码十分好懂

    那么矩阵快速幂也是一样的 只不过把*换成了mul函数



    用计算机模拟矩阵乘法是这样的

    struct mat{
        long long  m[100][100];//这里不开ll会死人
    };
    mat mul(mat x,mat y){
        mat r;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                r.m[i][j] = 0;
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                for(int k=1;k<=n;k++){
                    r.m[i][j] += (x.m[i][k] * y.m[k][j]) % p;
                    r.m[i][j] %= p;
                }
            }
        }
        return r;
    }

    首先定义一个矩阵并赋初值0 然后模拟乘的过程

    什么?你想看矩阵乘法的公式?我不会MARKDOWN啊百度麻烦您了

    还有一个小问题 就是在矩阵乘法中 什么矩阵是“1"?

    答案就是(1,1)(2,2)(3,3).....(N,N)=1 其他地方为0的矩阵(可以自己手动模拟一下)

    好了上完整代码

    #include<bits/stdc++.h>
    #define ll long long
    #define p 1000000007
    
    using namespace std;
    
    struct mat{
        long long  m[100][100];
    }e,ans1,ans2;
    
    ll k,n;
    
    mat mul(mat x,mat y){
        mat r;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                r.m[i][j] = 0;
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                for(int k=1;k<=n;k++){
                    r.m[i][j] += (x.m[i][k] * y.m[k][j]) % p;
                    r.m[i][j] %= p;
                }
            }
        }
        return r;
    }
    
    mat pow(mat x,ll y){
        mat ans = e;
        while (y>0){
            if(y&1){
                ans = mul(ans,x);
            }
            x=mul(x,x);
            y>>=1;
        }
        return ans;
    }
    
    int main(){
        cin>>n>>k;
        for(int i=1;i<=n;i++) e.m[i][i] = 1;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&ans1.m[i][j]);
            }
        }
        ans2 =pow (ans1,k); 
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                printf("%d ",ans2.m[i][j]);
            }
            cout<<endl;
        }
        return 0;
    }

    你会了这个才会矩阵加速之类乱七八糟的东西

    TAG:SIN_XIII ⑨

  • 相关阅读:
    How to change hostname on SLE
    How to install starDIct on suse OS?
    python logging usage
    How to reset password for unknow root
    How to use wget ?
    How to only capute sub-matched character by grep
    How to inspect who is caller of func and who is the class of instance
    How to use groovy script on jenkins
    Vim ide for shell development
    linux高性能服务器编程 (二) --IP协议详解
  • 原文地址:https://www.cnblogs.com/SINXIII/p/10542294.html
Copyright © 2011-2022 走看看