zoukankan      html  css  js  c++  java
  • 模板

    线性递推公式找递推矩阵的方法:

    https://blog.csdn.net/synapse7/article/details/18790165

    构造方法:规定由递推矩阵A,左乘由项构成的矩阵F,其中矩阵A的第一列为对应系数,左下角为单位矩阵,右下角为零矩阵。

    对于递推式的常数C,在矩阵F中增加最后一行C,在A的最右列增加两个1(通常选右上角和左下角)。

    对于递推式的C的n次方,在矩阵F中增加最后一行C的n次方,在A的最右列增加两个C(通常选右上角和左下角)。

    以斐波那契数列为例,这里使用了快速乘进一步防止溢出。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define MAXN 2
    
    ll mod=1000000007;
    
    //快速乘 a*b%p 防止乘法溢出ll
    ll qmut(ll a,ll b){
        ll res=0;
        while(b){
            if(b&1) res=(res+a)%mod;
            a=(a+a)%mod;
            b>>=1;
        }
        return res;
    }
    
    class Matrix {
      public:
        ll m[MAXN][MAXN];
        //二维数组存放矩阵
        Matrix() {
            memset(m,0,sizeof(m));
        }
        //对数组的初始化
        void init(ll num[MAXN][MAXN]) {
            for(int i = 0 ; i < MAXN ; i++) {
                for(int j = 0 ; j < MAXN ; j++) {
                    m[i][j] = num[i][j];
                }
            }
        }
    
        Matrix operator*(Matrix &m1) {
            int i, j, k;
            Matrix t;
            for(i = 0; i < MAXN; i++) {
                for(j = 0; j < MAXN; j++) {
                    t.m[i][j] = 0;
                    for(k = 0 ; k < MAXN ; k++)
                        t.m[i][j] = (t.m[i][j] + qmut(m[i][k],m1.m[k][j]))%mod;
                }
            }
            return t;
        }
    
        Matrix qpow(ll n) {
            Matrix t;
            for(int i = 0 ; i < MAXN ; i++)
                for(int j = 0 ; j < MAXN ; j++)
                    t.m[i][j] = (i == j);
    
            Matrix M=*this;
            while(n) {
                if(n & 1)
                    t = t * M;
                n = n >> 1;
                M = M * M;
            }
            return t;
        }
    
        void show() {
            for(int i=0; i<MAXN; i++) {
                for(int j=0; j<MAXN; j++) {
                    cout<<m[i][j]<<" ";
                }
                cout<<endl;
            }
            cout<<endl;
        }
    };
    
    int main() {
        ll n;
        cin>>n;
    
        if(n<=2){
            cout<<1<<endl;
            return 0;
        }
    
        ll num[MAXN][MAXN];
    
        Matrix A;
        memset(num,0,sizeof(num));
        num[0][1]=num[1][0]=num[1][1]=1;
        A.init(num);//初始化A矩阵
        //A.show();
    
        Matrix ini;
        memset(num,0,sizeof(num));
        num[0][0]=1;
        num[1][0]=1;
    
        ini.init(num);
        //ini.show();
    
        Matrix An=A.qpow(n-2); //求出矩阵的快速幂
        //An.show();
    
        Matrix res=An*ini;
        //res.show();
    
        cout<<res.m[1][0]<<endl;
    }

    https://www.luogu.org/problemnew/show/P1939

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define MAXN 4
    
    ll mod=1000000007;
    
    //快速乘 a*b%p 防止乘法溢出ll
    ll qmut(ll a,ll b){
        ll res=0;
        while(b){
            if(b&1) res=(res+a)%mod;
            a=(a+a)%mod;
            b>>=1;
        }
        return res;
    }
    
    class Matrix {
      public:
        ll m[MAXN][MAXN];
        //二维数组存放矩阵
        Matrix() {
            memset(m,0,sizeof(m));
        }
        //对数组的初始化
        void init(ll num[MAXN][MAXN]) {
            for(int i = 0 ; i < MAXN ; i++) {
                for(int j = 0 ; j < MAXN ; j++) {
                    m[i][j] = num[i][j];
                }
            }
        }
    
        Matrix operator*(Matrix &m1) {
            int i, j, k;
            Matrix t;
            for(i = 0; i < MAXN; i++) {
                for(j = 0; j < MAXN; j++) {
                    t.m[i][j] = 0;
                    for(k = 0 ; k < MAXN ; k++)
                        t.m[i][j] = (t.m[i][j] + qmut(m[i][k],m1.m[k][j]))%mod;
                }
            }
            return t;
        }
    
        Matrix qpow(ll n) {
            Matrix t;
            for(int i = 0 ; i < MAXN ; i++)
                for(int j = 0 ; j < MAXN ; j++)
                    t.m[i][j] = (i == j);
    
            Matrix M=*this;
            while(n) {
                if(n & 1)
                    t = t * M;
                n = n >> 1;
                M = M * M;
            }
            return t;
        }
    
        void show() {
            for(int i=0; i<MAXN; i++) {
                for(int j=0; j<MAXN; j++) {
                    cout<<m[i][j]<<" ";
                }
                cout<<endl;
            }
            cout<<endl;
        }
    };
    
    int main() {
        int T;
        while(~scanf("%d",&T)){
            while(T--){
                int n;
                scanf("%d",&n);
    
                if(n<=3){
                    printf("%d
    ",1);
                    continue;
                }
    
                ll num[MAXN][MAXN];
    
                Matrix A;
                memset(num,0,sizeof(num));
                num[0][1]=num[1][2]=num[2][3]=num[3][1]=num[3][3]=1;
                A.init(num);//初始化A矩阵
                //A.show();
    
                Matrix ini;
                memset(num,0,sizeof(num));
                num[0][0]=1;
                num[1][0]=1;
                num[2][0]=1;
                num[3][0]=2;
    
                ini.init(num);
                //ini.show();
    
                Matrix An=A.qpow(n-4); //求出矩阵的快速幂
                //An.show();
    
                Matrix res=An*ini;
                //res.show();
    
                printf("%d
    ",res.m[3][0]);
            }
        }
    }

    带n的次方的矩阵快速幂,找出相邻两项的关系就可以,用杨辉三角就可以了。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define MAXN 8
    
    ll mod=2147493647;
    
    class Matrix {
      public:
        ll m[MAXN][MAXN];
        //二维数组存放矩阵
        Matrix() {
            memset(m,0,sizeof(m));
        }
        //对数组的初始化
        void init(ll num[MAXN][MAXN]) {
            for(int i = 0 ; i < MAXN ; i++) {
                for(int j = 0 ; j < MAXN ; j++) {
                    m[i][j] = num[i][j];
                }
            }
        }
    
        Matrix operator*(Matrix &m1) {
            int i, j, k;
            Matrix t;
            for(i = 0; i < MAXN; i++) {
                for(j = 0; j < MAXN; j++) {
                    t.m[i][j] = 0;
                    for(k = 0 ; k < MAXN ; k++)
                        t.m[i][j] = (t.m[i][j] + m[i][k]*m1.m[k][j]%mod)%mod;
                }
            }
            return t;
        }
    
        Matrix qpow(ll n) {
            Matrix t;
            for(int i = 0 ; i < MAXN ; i++)
                for(int j = 0 ; j < MAXN ; j++)
                    t.m[i][j] = (i == j);
    
            Matrix M=*this;
            while(n) {
                if(n & 1)
                    t = t * M;
                n = n >> 1;
                M = M * M;
            }
            return t;
        }
    
        void show() {
            for(int i=0; i<MAXN; i++) {
                for(int j=0; j<MAXN; j++) {
                    cout<<m[i][j]<<" ";
                }
                cout<<endl;
            }
            cout<<endl;
        }
    };
    
    int main() {
        int T;
        while(~scanf("%d",&T)) {
            while(T--) {
                ll n,a,b;
                scanf("%lld%lld%lld",&n,&a,&b);
                if(n==1) {
                    printf("%lld
    ",a);
                } else if(n==2) {
                    printf("%lld
    ",b);
                } else {
                    ll num[MAXN][MAXN];
    
                    Matrix A;
                    memset(num,0,sizeof(num));
                    num[0][0]=1;
                    num[1][0]=1;
                    num[1][1]=1;
                    for(int i=2;i<=5;i++){
                        num[i][0]=1;
                        for(int j=1;j<=i;j++){
                            num[i][j]=num[i-1][j-1]+num[i-1][j];
                        }
                    }
                    num[6][7]=1;
                    num[7][5]=3;
                    num[7][6]=3;
                    num[7][7]=2;
                    A.init(num);//初始化A矩阵
                    //A.show();
    
                    Matrix ini;
                    memset(num,0,sizeof(num));
                    num[0][0]=1;
                    num[1][0]=3;
                    num[2][0]=9;
                    num[3][0]=27;
                    num[4][0]=81;
                    num[5][0]=243;
                    num[6][0]=a;
                    num[7][0]=b;
    
                    ini.init(num);
                    //ini.show();
    
                    Matrix An=A.qpow(n-2); //求出矩阵的快速幂
                    //An.show();
    
                    Matrix res=An*ini;
                    //res.show();
                    printf("%lld
    ",res.m[7][0]);
                }
            }
        }
    }
  • 相关阅读:
    移动端iOS点击闪烁
    盒子布局(标准)
    zepto.js 自定义打包集成其他模块构建流程
    一种移动端position:absolute布局:
    CSS基础:text-overflow:ellipsis溢出文本显示省略号的详细方法_CSS教程
    ie8 下的半透明 background:rgba 与opacity失效 兼容办法
    在webstorm中编译less,以及压缩css
    JS截取字符串substr 和 substring方法的区别
    array数据处理
    git 使用小结
  • 原文地址:https://www.cnblogs.com/Yinku/p/10398954.html
Copyright © 2011-2022 走看看