题意

求解递推式 \(f(n)=a_1*f(n-1)+a_2*f(n-2)+....+a_d*f(n-d)\) 的第 \(n\) 项模以 \(m\)。

\(1 \leq n \leq 2^{31}-1\)

\(1 \leq m \leq 46340\)

\(1 \leq d \leq 15\)

思路

矩阵乘法最经典的运用之一。先大致介绍一下矩阵乘法:

对于一个矩阵 \(A_{np}\) ,另一个矩阵 \(B_{pm}\) ,设它们的乘积为 \(C_{n,m}\) ,有 \(C_{i,j}=\displaystyle\sum_{k=1}^pA_{i,k}B_{k,j}\) .

例如对于一个矩阵 \(\begin{pmatrix}a_{1,1}&a_{1,2}&a_{1,3}\\a_{2,1}&a_{2,2}&a_{2,3}\end{pmatrix}​\) ,和另一个矩阵 \(\begin{pmatrix}b_{1,1}&b_{1,2}\\b_{2,1}&b_{2,2}\\b_{3,1}&b_{3,2}\end{pmatrix}​\) ,它们的积为:

\[\begin{pmatrix}
a_{1,1}b_{1,1}+a_{1,2}b_{2,1}+a_{1,3}b_{3,1} & a_{1,1}b_{1,2}+a_{1,2}b_{2,2}+a_{1,3}b_{3,2}\\
a_{2,1}b_{1,1}+a_{2,2}b_{2,1}+a_{2,3}b_{3,1} & a_{2,1}b_{1,2}+a_{2,2}b_{2,2}+a_{2,3}b_{3,2}
\end{pmatrix}
\]

从定义式可以看出来,矩阵乘法不满足交换律,但满足结合律。满足结合律,就说明了可以快速幂。

矩阵乘法的题目的根本想法是构造矩阵。对于这道题,可以先构造出矩阵 \(A_{1d}\) ,分别表示数列 \(f\) 的前 \(d\) 项,那么只需要再构造出一个 \(B_{dd}\) ,使得 \(A_{1d}B_{dd}\) 得到 \(f\) 数列的第 \(2\) 项到第 \(d+1\) 项即可。具体构造见代码:

代码

#include<bits/stdc++.h>
#define FOR(i,x,y) for(int i=(x),i##END=(y);i<=i##END;++i)
#define DOR(i,x,y) for(int i=(x),i##END=(y);i>=i##END;--i)
typedef long long LL;
using namespace std;
const int N=20;
int P;
struct Matrix
{
int n,m,a[N][N];
int *operator [](const int x){return a[x];}
void resize(int _n,int _m){n=_n,m=_m;}
Matrix operator *(const Matrix &_)const
{
Matrix res;
res.n=n,res.m=_.m;
FOR(i,1,n)FOR(j,1,_.m)
{
res[i][j]=0;
FOR(k,1,m)(res[i][j]+=(a[i][k]*_.a[k][j])%P)%=P;
}
return res;
}
Matrix operator *=(const Matrix &_){return (*this)=(*this)*_;}
};
int n,d; Matrix Pow(Matrix a,int p)
{
Matrix res;res.resize(a.n,a.n);
FOR(i,1,res.n)FOR(j,1,res.m)res[i][j]=(i==j); //res初始值是一个"单位1"的矩阵
for(;p>0;p>>=1,a*=a)if(p&1)res*=a;
return res;
} int main()
{
while(scanf("%d%d%d",&d,&n,&P),d|n|P)
{
Matrix A,B;A.resize(1,d),B.resize(d,d);
FOR(i,1,d)FOR(j,1,d-1)B[i][j]=(i==j+1);
FOR(i,1,d)scanf("%d",&B[d-i+1][d]),B[d-i+1][d]%=P;
FOR(i,1,d)scanf("%d",&A[1][i]),A[1][i]%=P;
if(n<=d)printf("%d\n",A[1][n]);
else
{
A*=Pow(B,n-d);
printf("%d\n",A[1][d]);
}
}
return 0;
}

UVA 10870 Recurrences(矩阵乘法)的更多相关文章

  1. UVA 10870 - Recurrences(矩阵高速功率)

    UVA 10870 - Recurrences 题目链接 题意:f(n) = a1 f(n - 1) + a2 f(n - 2) + a3 f(n - 3) + ... + ad f(n - d), ...

  2. UVa 10870 Recurrences (矩阵快速幂)

    题意:给定 d , n , m (1<=d<=15,1<=n<=2^31-1,1<=m<=46340).a1 , a2 ..... ad.f(1), f(2) .. ...

  3. UVA - 10870 Recurrences 【矩阵快速幂】

    题目链接 https://odzkskevi.qnssl.com/d474b5dd1cebae1d617e6c48f5aca598?v=1524578553 题意 给出一个表达式 算法 f(n) 思路 ...

  4. 矩阵快速幂 UVA 10870 Recurrences

    题目传送门 题意:f(n) = a1f(n − 1) + a2f(n − 2) + a3f(n − 3) + . . . + adf(n − d), for n > d,求f (n) % m.训 ...

  5. UVa 10870 - Recurrences

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  6. uva 10870 递推关系矩阵快速幂模

    Recurrences Input: standard input Output: standard output Consider recurrent functions of the follow ...

  7. UVa 10870 & 矩阵快速幂

    题意: 求一个递推式(不好怎么概括..)的函数的值. 即 f(n)=a1f(n-1)+a2f(n-2)+...+adf(n-d); SOL: 根据矩阵乘法的定义我们可以很容易地构造出矩阵,每次乘法即可 ...

  8. UVA - 12183 :Top Secret(N^2的循环矩阵乘法)

    pro:N个数排成一圈.一次操作为,每个位置的数+=L*左+R*右,保留x为整数. 问S轮操作后每个位置的值. N<=1000,S<=2^30,x<=9 . sol:不难想到矩阵乘法 ...

  9. 矩阵乘法优化DP复习

    前言 最近做毒瘤做多了--联赛难度的东西也该复习复习了. Warning:本文较长,难度分界线在"中场休息"部分,如果只想看普及难度的可以从第五部分直接到注意事项qwq 文中用(比 ...

随机推荐

  1. 【转】基于Python的接口测试框架实例

    下面小编就为大家带来一篇基于Python的接口测试框架实例.小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧   背景 最近公司在做消息推送,那么自然就会产生很多接口,测试 ...

  2. 【Linux学习三】VI/VIM全屏文本编辑器

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 一.打开关闭文件打开文件:vim /path/to/somefilev ...

  3. ssh 免登录

    1. 生成 ssh 公钥和私钥 xiluhua@vm-xiluhua ~ $ ssh-keygen Generating public/private rsa key pair. Enter file ...

  4. selenium-grid 分布式 实现同一脚本在不同pc上运行

    1.使用版本:selenium 3.11.0chrome 65phantomjs 2.1.1selenium-server selenium-server-standalone-2.46.0.jar ...

  5. python中的作用域以及内置函数globals()-全局变量、locals()-局部变量

    在python中,函数会创建一个自己的作用域,也称为为命名空间.这意味着在函数内部访问某个变量时,函数会优先在自己的命名空间中寻找. 通过内置函数globals()返回的是python解释器能知道的变 ...

  6. MySQL存储引擎MyISAM与InnoDB区别总结整理

    在MySQL的 可重复读隔离级别 中,是解决了幻读的读问题的. 1. MySQL默认存储引擎的变迁 在MySQL 5.5之前的版本中,默认的搜索引擎是MyISAM,从MySQL 5.5之后的版本中,默 ...

  7. GIT库代码管理规范

    GIT库代码管理规范 一. 规范要求 1. 每个项目建立单独的GIT库.每个GIT库包括两条线,命名规则如下: 开发线(测试):项目名称_DEV 生产线(正式):项目名称 2. 每条线只允许增量不允许 ...

  8. android本地数据库,微信数据库WCDB for Android 使用实例

    android本地数据库,微信数据库WCDB for Android 使用实例 Home · Tencent/wcdb Wikihttps://github.com/Tencent/wcdb/wiki ...

  9. The Little Prince-summary

    The Little Prince-summary 这些年 ”寂寞”这个词使用频率越来越高 这些年 不管有钱没钱 有对象没对象的人 入夜时分总是心里空空 不知生活的意义是什么 我们不喜欢一座城市 对一 ...

  10. jdbc连接oracle数据库问题

    下面是JDBC连接oracle数据库流程: String dbURL = "jdbc:oracle:thin:@url:1521:service_name"; String use ...