先从最基础的矩阵快速幂加速递推开始。

HDU 1005 Number Sequence

|f[n-2],f[n-1]|* |0 B| =|f[n-1], B*f[n-2]+A*f[n-1]|=|f[n-1],f[n]|

          |1 A|

建立矩阵如上然后利用快速幂求解即可。答案是mat[0][1]。

#include<iostream>
#include<vector>
#include<cmath>
#include<map>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cmath>
#include<set>
#include<string>
#define INF 1000000005
#define LL long long
using namespace std;
;
struct Matrix
{
    int n,m;
    int a[MAXN][MAXN];
    ,)
    {
        n=x;
        m=y;
        memset(a,,sizeof(a));
    }
    Matrix operator * (const Matrix &b)const
    {
        Matrix tmp;
        tmp.clear(n,b.m);
        ; i<n; ++i)
            ; j<b.m; ++j)
                ; k<m; ++k)
                {
                    tmp.a[i][j]+=a[i][k]*b.a[k][j];
                    tmp.a[i][j]%=;
                }
        return tmp;
    }
};
Matrix quickPow(Matrix mat,int n)
{
    Matrix res;
    res.clear(,);
    res.a[][]=res.a[][]=;
    while(n)
    {
        ) res=res*mat;
        mat=mat*mat;
        n=n>>;
    }
    return res;
}
int main()
{
    int A,B,n;
    while(scanf("%d%d%d",&A,&B,&n)!=EOF)
    {
        if(!A&&!B&&!n) break;
        ||n==)
        {
            puts(");
            continue;
        }
        Matrix mat;
        mat.clear(,);
        mat.a[][]=;
        mat.a[][]=B;
        mat.a[][]=;
        mat.a[][]=A;
        Matrix f;
        f.clear(,);
        f.a[][]=;
        f.a[][]=;
        n-=;
        Matrix s=f*quickPow(mat,n);
        printf(][])%);
    }
    ;
}

HDU 4920 Matrix multiplication

矩阵乘法,直接算会超时。由于是模3,所以0很多,也就是稀疏矩阵。可以优化。

参见下文:http://www.cnblogs.com/jackiesteed/articles/2021604.html

#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<string>
#define LL long long
using namespace std;
][],B[][];
][];
int n;
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        ; i<=n; ++i)
            ; j<=n; ++j)
            {
                scanf("%d",&A[i][j]);
                A[i][j]%=;
            }
        ; i<=n; ++i)
            ; j<=n; ++j)
            {
                scanf("%d",&B[i][j]);
                B[i][j]%=;
            }
        memset(C,,sizeof(C));
        ; i<=n; ++i)
            ; j<=n; ++j)
            {
                ) continue;
                ; k<=n; ++k)
                    C[i][k]+=A[i][j]*B[j][k];
            }
        ; i<=n; ++i)
        {
            ; j<=n; ++j)
                ) printf();
                );
            printf("\n");
        }
    }
    ;
}

HDU 1575 Tr A

求矩阵的迹。直接快速幂即可。

#include<iostream>
#include<vector>
#include<cmath>
#include<map>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cmath>
#include<set>
#include<string>
#define INF 1000000005
#define LL long long
using namespace std;
;
struct Matrix
{
    int n,m;
    int a[MAXN][MAXN];
    ,)
    {
        n=x;
        m=y;
        memset(a,,sizeof(a));
    }
    Matrix operator * (const Matrix &b)const
    {
        Matrix tmp;
        tmp.clear(n,b.m);
        ; i<n; ++i)
            ; j<b.m; ++j)
            {
                ; k<b.m; ++k)
                {
                    ==a[i][j]) continue;//优化!
                    tmp.a[i][k]+=a[i][j]*b.a[j][k];
                    tmp.a[i][k]%=;
                }
            }
        return tmp;
    }
    void setOne(int x)
    {
        clear(x,x);
        ; i<x; ++i)
            a[i][i]=;
    }
};
Matrix one;
Matrix quickPow(Matrix mat,int n)
{
    Matrix res=one;
    while(n)
    {
        ) res=res*mat;
        mat=mat*mat;
        n=n>>;
    }
    return res;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        int n,k;
        scanf("%d%d",&n,&k);
        one.setOne(n);
        Matrix mat;
        mat.clear(n,n);
        ;i<n;++i)
            ;j<n;++j)
            scanf("%d",&mat.a[i][j]);
        mat=quickPow(mat,k);
        ;
        ;i<n;++i)
        {
            ans+=mat.a[i][i];
            ans%=;
        }
        printf("%d\n",ans);
    }
    ;
}

HDU 1757 A Simple Math Problem

一个简单的递推,建立矩阵后,快速幂。

#include<iostream>
#include<vector>
#include<cmath>
#include<map>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cmath>
#include<set>
#include<string>
#define INF 1000000005
#define LL long long
using namespace std;
;
int M;
struct Matrix
{
    int n,m;
    int a[MAXN][MAXN];
    ,)
    {
        n=x;
        m=y;
        memset(a,,sizeof(a));
    }
    Matrix operator * (const Matrix &b)const
    {
        Matrix tmp;
        tmp.clear(n,b.m);
        ; i<n; ++i)
            ; j<b.m; ++j)
            {
                ; k<b.m; ++k)
                {
                    ==a[i][j]) continue;//优化!
                    tmp.a[i][k]+=a[i][j]*b.a[j][k];
                    tmp.a[i][k]%=M;
                }
            }
        return tmp;
    }
    void setOne(int x)
    {
        clear(x,x);
        ; i<x; ++i)
            a[i][i]=;
    }
};
Matrix one;
Matrix quickPow(Matrix mat,int n)
{
    Matrix res=one;
    while(n)
    {
        ) res=res*mat;
        mat=mat*mat;
        n=n>>;
    }
    return res;
}
int main()
{
    int k;
    one.setOne();
    while(scanf("%d%d",&k,&M)!=EOF)
    {
        Matrix mat;
        mat.clear(,);
        ; i<; ++i)
            mat.a[i+][i]=;
        ; i<; ++i)
            scanf(-i][]);
        ) printf("%d\n",k%M);
        else
        {
            Matrix f;
            f.clear(,);
            ; i<; ++i)
                f.a[][i]=i;
            k-=;
            f=f*quickPow(mat,k);
            printf(][]);
        }
    }
    ;
}

UVa 10870  Recurrences

与上面类型相似的题,建立矩阵,再快速幂加速。注意会超int。

#include<iostream>
#include<vector>
#include<cmath>
#include<map>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cmath>
#include<set>
#include<string>
#define INF 1000000005
#define LL long long
using namespace std;
;
int M;
struct Matrix
{
    int n,m;
    LL a[MAXN][MAXN];
    ,)
    {
        n=x;
        m=y;
        memset(a,,sizeof(a));
    }
    Matrix operator * (const Matrix &b)const
    {
        Matrix tmp;
        tmp.clear(n,b.m);
        ; i<n; ++i)
            ; j<b.m; ++j)
            {
                ; k<b.m; ++k)
                {
                    ==a[i][j]) continue;//优化!
                    tmp.a[i][k]+=a[i][j]*b.a[j][k];
                    tmp.a[i][k]%=M;
                }
            }
        return tmp;
    }
    void setOne(int x)
    {
        clear(x,x);
        ; i<x; ++i)
            a[i][i]=;
    }
};
Matrix one;
Matrix quickPow(Matrix mat,LL n)
{
    Matrix res=one;
    while(n)
    {
        ) res=res*mat;
        mat=mat*mat;
        n=n>>;
    }
    return res;
}
int main()
{
    int d,n;
    while(scanf("%d%d%d",&d,&n,&M)!=EOF)
    {
        if(!d&&!n&&!M) break;
        one.setOne(d);
        Matrix mat;
        mat.clear(d,d);
        ; i<d; ++i)
            mat.a[i+][i]=;
        ; i<d; ++i)
            scanf(-i][d-]);
        Matrix f;
        f.clear(,d);
        ; i<d; ++i)
            scanf(][i]);
        if(n<=d)
            printf(][n-]%M);
        else
        {
            n-=d;
            f=f*quickPow(mat,n);
            printf(][d-]%M);
        }
    }
    ;
}

POJ 3734 Blocks

递推+矩阵快速幂。

设计状态的时候要考虑所有可能的情况,保证无重复无遗漏,再考虑转移。最后用矩阵加速。

#include<iostream>
#include<vector>
#include<cmath>
#include<map>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cmath>
#include<set>
#include<string>
#define INF 1000000005
#define LL long long
using namespace std;
;
;
struct Matrix
{
    int n,m;
    int a[MAXN][MAXN];
    Matrix(,):n(x),m(y)
    {
        memset(a,,sizeof(a));
    }
    ,)
    {
        n=x;
        m=y;
        memset(a,,sizeof(a));
    }
    Matrix operator * (const Matrix &b)const
    {
        Matrix tmp;
        tmp.clear(n,b.m);
        ; i<n; ++i)
            ; j<b.m; ++j)
            {
                ; k<b.m; ++k)
                {
                    ==a[i][j]) continue;//ÓÅ»¯£¡
                    tmp.a[i][k]+=a[i][j]*b.a[j][k];
                    tmp.a[i][k]%=M;
                }
            }
        return tmp;
    }
    void setOne(int x)
    {
        clear(x,x);
        ; i<x; ++i)
            a[i][i]=;
    }
};
Matrix one;
Matrix quickPow(Matrix mat,int n)
{
    Matrix res=one;
    while(n)
    {
        ) res=res*mat;
        mat=mat*mat;
        n=n>>;
    }
    return res;
}
int main()
{
    one.setOne();
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        Matrix mat(,);
        mat.a[][]=,mat.a[][]=,mat.a[][]=;
        mat.a[][]=,mat.a[][]=,mat.a[][]=;
        mat.a[][]=,mat.a[][]=,mat.a[][]=;
        Matrix f(,);
        f.a[][]=;
        Matrix ans=f*quickPow(mat,n);
        printf(][]);
    }
    ;
}

POJ 3420 Quad Tiling

这个题的关键是在求递推式。

设dp[i]表示填满前i个方块的种数。那么从dp[i-1]转移有1种情况,从dp[i-2]转移有4种情况,在之后从dp[i-a],如果a是奇数有2种情况,a是偶数有3种情况。

这样最终化简得dp[i]=dp[i-1]+5dp[i-2]+dp[i-3]-dp[i-4]

#include<iostream>
#include<vector>
#include<cmath>
#include<map>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cmath>
#include<set>
#include<string>
#define INF 1000000005
#define LL long long
using namespace std;
;
int M;
struct Matrix
{
    int n,m;
    int a[MAXN][MAXN];
    Matrix(,):n(x),m(y)
    {
        memset(a,,sizeof(a));
    }
    ,)
    {
        n=x;
        m=y;
        memset(a,,sizeof(a));
    }
    Matrix operator * (const Matrix &b)const
    {
        Matrix tmp;
        tmp.clear(n,b.m);
        ; i<n; ++i)
            ; j<b.m; ++j)
            {
                ; k<b.m; ++k)
                {
                    ==a[i][j]) continue;//优化
                    tmp.a[i][k]+=a[i][j]*b.a[j][k];
                    tmp.a[i][k]%=M;
                }
            }
        return tmp;
    }
    void setOne(int x)
    {
        clear(x,x);
        ; i<x; ++i)
            a[i][i]=;
    }
};
Matrix one;
Matrix quickPow(Matrix mat,int n)
{
    Matrix res=one;
    )
    {
        ) res=res*mat;
        mat=mat*mat;
        n=n>>;
    }
    return res;
}
int main()
{
    int n;
    one.setOne();
    while(scanf("%d%d",&n,&M)!=EOF)
    {
        if(!n&&!M) break;
        Matrix mat(,);
        ; i<; ++i)
            mat.a[i+][i]=;
        mat.a[][]=-,mat.a[][]=,mat.a[][]=,mat.a[][]=;
        Matrix f(,);
        f.a[][]=,f.a[][]=,f.a[][]=,f.a[][]=;
        ) printf(][n]%M);
        else
        {
            n-=;
            Matrix s=f*quickPow(mat,n);
            printf(][]);
        }
    }
    ;
}

ZOJ 3690 Choosing number

a[i]表示第i个人选小于等于k的数字的合法种数,a[i]=(k-1)*a[i]+k*b[i]

b[i]表示第i个人选大于等于k的数字的合法种数,b[i]=(m-k)*a[i]+(m-k)*b[i]

a[0]=0,b[0]=1,答案是a[n]+b[n]

建立矩阵快速幂计算即可。

#include<iostream>
#include<vector>
#include<cmath>
#include<map>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cmath>
#include<set>
#include<string>
#define INF 1000000005
#define LL long long
using namespace std;
;
;
struct Matrix
{
    int n,m;
    LL a[MAXN][MAXN];
    Matrix(,):n(x),m(y)
    {
        memset(a,,sizeof(a));
    }
    ,)
    {
        n=x;
        m=y;
        memset(a,,sizeof(a));
    }
    Matrix operator * (const Matrix &b)const
    {
        Matrix tmp;
        tmp.clear(n,b.m);
        ; i<n; ++i)
            ; j<m; ++j)
            {
                ; k<b.m; ++k)
                {
                    ==a[i][j]) continue;//优化!
                    tmp.a[i][k]+=a[i][j]*b.a[j][k];
                    tmp.a[i][k]%=M;
                }
            }
        return tmp;
    }
    void setOne(int x)
    {
        clear(x,x);
        ; i<x; ++i)
            a[i][i]=;
    }
};
Matrix one;
Matrix quickPow(Matrix mat,int n)
{
    Matrix res=one;
    while(n)
    {
        ) res=res*mat;
        mat=mat*mat;
        n=n>>;
    }
    return res;
}
int main()
{
    int n,m,k;
    one.setOne();
    while(scanf("%d%d%d",&n,&m,&k)!=EOF)
    {
        Matrix mat(,);
        mat.a[][]=k-,mat.a[][]=k;
        mat.a[][]=m-k,mat.a[][]=m-k;
        Matrix f(,);
        f.a[][]=,f.a[][]=;
        Matrix s=quickPow(mat,n)*f;
        printf(][]+s.a[][])%M);
    }
    ;
}

ACM 矩阵题目整理的更多相关文章

  1. ACM 字符串 题目整理

    AC自动机 UVa 11468  Substring AC自动机+概率DP. 注意要补全不存在的边. 为什么要补全不存在的边呢?补全以后可以直接找到状态的转移,即从所有子节点就可以实现所有状态转移. ...

  2. Noip往年题目整理

    Noip往年题目整理 张炳琪 一.历年题目 按时间倒序排序 年份 T1知识点 T2知识点 T3知识点 得分 总体 2016day1 模拟 Lca,树上差分 期望dp 144 挺难的一套题目,偏思维难度 ...

  3. NOIp初赛题目整理

    NOIp初赛题目整理 这个 blog 用来整理扶苏准备第一轮 csp 时所做的与 csp 没 有 关 系 的历年 noip-J/S 初赛题目,记录了一些我从不知道的细碎知识点,还有一些憨憨题目,不定期 ...

  4. ACM 暴力搜索题 题目整理

    UVa 129 Krypton Factor 注意输出格式,比较坑爹. 每次要进行处理去掉容易的串,统计困难串的个数. #include<iostream> #include<vec ...

  5. ACM - 动态规划专题 题目整理

    CodeForces 429B  Working out 预处理出从四个顶点到某个位置的最大权值,再枚举相遇点,相遇的时候只有两种情况,取最优解即可. #include<iostream> ...

  6. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

  7. 第八届蓝桥杯c/c++省赛题目整理

    第一题 标题: 购物单 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推辞. 这不,XX大促销又来了!老板夫人开出了长长的购物单,都 ...

  8. ACM金牌选手整理的【LeetCode刷题顺序】

    算法和数据结构知识点图 首先,了解算法和数据结构有哪些知识点,在后面的学习中有 大局观,对学习和刷题十分有帮助. 下面是我花了一天时间花的算法和数据结构的知识结构,大家可以看看. 后面是为大家 精心挑 ...

  9. 内工大acm校赛--整理代码

    题目:小明搜到一行无缩进无换行代码,请帮小明整理代码.无for语句和case语句,而且只有一个主函数.你只要控制注意“:”“{”“}”这三个符号带来的缩进和换行效果就行. Input: 输入只有一行, ...

随机推荐

  1. sprint2 项目的粗略展示

  2. easyui DataGrid 工具类之 列属性class

    public class ColumnVO { /**     * 列标题文本     */    private String title; /**     * 列字段名称     */    pr ...

  3. R开发环境(Eclipse+StatET)

    引用:http://cos.name/2008/12/eclipse-statet-for-r-editor/ StatET(www.walware.de/goto/statet) 1. 安装软件 s ...

  4. Duilib实现QQ聊天窗口晃动

    转载:http://blog.csdn.net/arbboter/article/details/26282717 转载:http://blog.csdn.net/zerolusta/article/ ...

  5. GZFramework代码生成器插件使用教程

    代码生成器分两种 1.基于独立exe生成程序 直接运行软件目录下GZFrameworkCodeGenerate.exe文件即可 2.基于VS插件生成 目录中分为两部分:全局缓存和VS插件 1.添加全局 ...

  6. 用excel做差异表达

    首先准备数据:表达矩阵 ACC.uncv2.mRNAseq_RSEM_normalized_log2.txt(以下载的TCGA的数据,log之后的) 上面数据中01为tumor,11为normal 我 ...

  7. Spring 数据库配置用户名和密码加密

    单个数据库配置 : 一般spring容器启动时,通过PropertyPlaceholderConfigurer类读取jdbc.properties文件里的数据库配置信息.通过这个原理,我们把加密后的数 ...

  8. (七)HTTP协议

    HTTP协议报文基本格式 HTTP协议报文基本格式       HTTP协议(Hypertext Transfer Protocol――超文本传输协议),浏览器端(客户端)向WEB服务器端访问页面的过 ...

  9. 【Todo】网络编程学习-面向工资编程

    https://zhuanlan.zhihu.com/p/20204159 这个系列真的非常好,好好领会学习一下

  10. IDEA maven项目 包不能导入问题 全是红线

    情况如图所示,红线的话里肯定是没有maven包的 1.检查pom.xml是否报错 报错 右键添加一下 2.点击 3.出现错误提示 4.百度解决