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 ⑨

  • 相关阅读:
    CF140C New Year Snowmen
    CF1131G Most Dangerous Shark
    莫比乌斯函数&欧拉函数&筛法 综合运用
    【51nod1220】约数之和
    题解[CF1228E Another Filling the Grid]
    dsu on tree学习笔记
    线性基学习笔记
    题解[CF895C Square Subsets]
    博弈论学习笔记
    题解[ [JSOI2007]文本生成器 ]
  • 原文地址:https://www.cnblogs.com/SINXIII/p/10542294.html
Copyright © 2011-2022 走看看