zoukankan      html  css  js  c++  java
  • 矩阵快速幂——POJ3070

    矩阵快速幂和普通的快速幂差不多,只不过写起来比较麻烦一点,需要重载*运算符。

    模板:

    struct mat
    {
        int m[maxn][maxn];
    }unit;
    
    mat operator * (mat a,mat b)
    {
        mat ret;
        ll x;
        for(int i=0;i < n;i++)
            for(int j=0;j < n;j++)
            {
                x = 0;
                for(int k=0;k < n;k++)
                    x += mod((ll)a.m[i][k]*b.m[k][j]);
                ret.m[i][j] = mod(x);
            }
        return ret;
    }
    
    void init_unit()             //初始化单位矩阵
    {
        for(int i=0;i < maxn;i++)
            unit.m[i][i] = 1;
        return;
    }
    
    mat pow_mat(mat a,ll n)
    {
        mat ret = unit;
        while(n)
        {
            if(n&1) ret = ret*a;
            a = a*a;
            n >>= 1;
        }
        return ret;
    }

    例题:POJ3070

    用矩阵快速幂求fib并取模10000

    有这个定理就很好求了:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long  ll;
    const int INF = 0x3f3f3f3f;
    const int moder = 10000;
    const int maxn = 110;
    #define mod(x)  ((x)%moder)
    int n = 2;
    
    struct mat
    {
        int m[maxn][maxn];
    }unit;
    
    mat operator * (mat a,mat b)
    {
        mat ret;
        ll x;
        for(int i=0;i < n;i++)
            for(int j=0;j < n;j++)
            {
                x = 0;
                for(int k=0;k < n;k++)
                    x += mod((ll)a.m[i][k]*b.m[k][j]);
                ret.m[i][j] = mod(x);
            }
        return ret;
    }
    
    void init_unit()
    {
        for(int i=0;i < maxn;i++)
            unit.m[i][i] = 1;
        return;
    }
    
    mat pow_mat(mat a,ll n)
    {
        mat ret = unit;
        while(n)
        {
            if(n&1) ret = ret*a;
            a = a*a;
            n >>= 1;
        }
        return ret;
    }
    
    
    
    
    int main()
    {
        ll p;
        init_unit();
        while(cin >> p)
        {
            if(p == -1) break;
            mat a;
            a.m[0][0] = 1;
            a.m[0][1] = 1;
            a.m[1][0] = 1;
            a.m[1][1] = 0;
            a = pow_mat(a,p);
            cout << a.m[0][1] << endl;
        }
        return 0;
    }

    要注意的是maxn开小一点,不然本地会炸。

  • 相关阅读:
    【译文】不是所有的 bug 都值得修复的
    11月第5周业务风控关注|重磅!瓜子二手车“遥遥领先”被罚天价1250万
    AutoCAD .NET二次开发(四)
    AutoCAD .NET二次开发(三)
    ArcGIS10.2下调试10.1的程序
    再遇1402,注册表权限问题
    ArcGIS Add-in——自动保存编辑
    只打开一个子窗体
    获取编辑器两种方法
    Adobe Acrobat Pro 11安装激活
  • 原文地址:https://www.cnblogs.com/cunyusup/p/8452675.html
Copyright © 2011-2022 走看看