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开小一点,不然本地会炸。

  • 相关阅读:
    【Python】 命名空间与LEGB规则
    【Python&数据结构】 抽象数据类型 Python类机制和异常
    【算法】 算法和数据结构绪论
    【网络】 数据链路层&物理层笔记
    svn -- svn图标解析
    svn -- svn数据仓库
    svn -- svn安装与配置
    svn -- svn简介
    mysql -- 远程访问mysql的解决方案
    css3 -- 自动生成序号(不使用JS,可任意排序)
  • 原文地址:https://www.cnblogs.com/cunyusup/p/8452675.html
Copyright © 2011-2022 走看看