SPOJ AMR10E Stocks Prediction --二分求和+矩阵快速幂
题意:给一个递推式S(n) = a1*S(n-1)+...+aR*S(n-R),要求S(k)+S(2k)+...+S(nk)的值。
分析:看到n的大小和递推式,容易想到矩阵快速幂。但是如何转化呢?
首先看到
我们用A表示上面的递推式中的R*R的那个矩阵,那么对于前面那个向量,每次乘上A^k之后都会变成(S(n + k)...)
那么对于初始的向量( S(R) S(R - 1) ... S(1) ) 如果这个向量当中包括 S(k) 我们可以直接对于每次要算的 S( i * k) 求和
也就是说这个向量乘上( I + A^k + (A^k)^2 + (A^k)^3 + ... + (A^k)^(N - 1))之后对应的 S(k) 所在的那个位置就变成了要求的和
而对于那个矩阵型的等比数列求和可以直接用二分求和(常用的技巧),这样就可以在限制的时间内完成计算了 (Gatevin)
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define Mod 1000000007
#define ll long long
using namespace std;
#define N 100007 ll s[],a[];
ll n;
int r; struct Matrix
{
ll m[][];
Matrix()
{
memset(m,,sizeof(m));
for(int i=;i<=;i++)
m[i][i] = ;
}
}; Matrix Mul(Matrix a,Matrix b)
{
Matrix res;
int i,j,k;
for(i=;i<=r;i++)
{
for(j=;j<=r;j++)
{
res.m[i][j] = ;
for(k=;k<=r;k++)
res.m[i][j] = (res.m[i][j]+(a.m[i][k]*b.m[k][j]%Mod))%Mod;
}
}
return res;
} Matrix add(Matrix a,Matrix b)
{
Matrix res;
memset(res.m,,sizeof(res.m));
int i,j;
for(i=;i<=r;i++)
for(j=;j<=r;j++)
res.m[i][j] = (a.m[i][j]+b.m[i][j])%Mod;
return res;
} Matrix fastm(Matrix a,ll b)
{
Matrix res;
while(b)
{
if(b&1LL)
res = Mul(res,a);
a = Mul(a,a);
b >>= ;
}
return res;
} Matrix getsum(Matrix a,ll b) //二分求矩阵等比数列和
{
Matrix I; //单位阵
if(b == 1LL)
return I;
if(b&1LL)
return add(getsum(a,b-1LL),fastm(a,b-1LL));
else
return Mul(getsum(a,b/2LL),add(I,fastm(a,b/2LL))); // (I+A^k+...+A^(n/2)k)*(I+A^(n/2)k)
} int main()
{
int t,i,j,k;
scanf("%d",&t);
while(t--)
{
scanf("%lld%d%d",&n,&r,&k);
for(i=;i<=r;i++)
scanf("%lld",&s[i]);
for(i=;i<=r;i++)
scanf("%lld",&a[i]);
Matrix A;
memset(A.m,,sizeof(A.m));
for(i=;i<=r;i++) //构造矩阵
{
A.m[][i] = a[i];
if(i < r)
A.m[i+][i] = ;
}
//求 I+A^k+A^(2k)+...+A^(n-1)k
Matrix base = fastm(A,k);
Matrix ans = getsum(base,n);
ll res = ;
if(k <= r) //第k项在给出的数内
{
for(i=;i<=r;i++)
res = (res + (s[i]*ans.m[r-k+][r-i+]%Mod))%Mod;
printf("%lld\n",res%Mod);
}
else //否则先算出s[r+1]...s[k]
{
for(i=r+;i<=k;i++)
{
s[i] = ;
for(j=;j<=r;j++)
s[i] = (s[i]+s[i-j]*a[j]%Mod)%Mod;
}
for(i=;i<=r;i++)
res = (res + (s[k-i+]*ans.m[][i])%Mod)%Mod;
printf("%lld\n",res%Mod);
}
}
return ;
}
SPOJ AMR10E Stocks Prediction --二分求和+矩阵快速幂的更多相关文章
- 【学术篇】SPOJ GEN Text Generator AC自动机+矩阵快速幂
还有5天省选才开始点字符串这棵技能树是不是太晚了点... ~题目の传送门~ AC自动机不想讲了QAQ.其实很久以前是学过然后打过板子的, 但也仅限于打过板子了~ 之前莫名其妙学了一个指针版的但是好像不 ...
- poj3233 题解 矩阵乘法 矩阵快速幂
题意:求S = A + A2 + A3 + … + Ak.(mod m) 这道题很明显可以用矩阵乘法,但是这道题的矩阵是分块矩阵, 分块矩阵概念如下:当一个矩阵A中的单位元素aij不是一个数值而是一个 ...
- POJ 3233 Matrix Power Series 矩阵快速幂+二分求和
矩阵快速幂,请参照模板 http://www.cnblogs.com/pach/p/5978475.html 直接sum=A+A2+A3...+Ak这样累加肯定会超时,但是 sum=A+A2+...+ ...
- 2017 ECJTU ACM程序设计竞赛 矩阵快速幂+二分
矩阵 Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Total Submission ...
- POJ 3233 Matrix Power Series (矩阵快速幂+二分求解)
题意:求S=(A+A^2+A^3+...+A^k)%m的和 方法一:二分求解S=A+A^2+...+A^k若k为奇数:S=(A+A^2+...+A^(k/2))+A^(k/2)*(A+A^2+...+ ...
- BZOJ.4180.字符串计数(后缀自动机 二分 矩阵快速幂/倍增Floyd)
题目链接 先考虑 假设S确定,使构造S操作次数最小的方案应是:对T建SAM,S在SAM上匹配,如果有S的转移就转移,否则操作数++,回到根节点继续匹配S.即每次操作一定是一次极大匹配. 简单证明:假设 ...
- POJ3233:Matrix Power Series(矩阵快速幂+二分)
http://poj.org/problem?id=3233 题目大意:给定矩阵A,求A + A^2 + A^3 + … + A^k的结果(两个矩阵相加就是对应位置分别相加).输出的数据mod m.k ...
- POJ 3233 Matrix Power Series 【经典矩阵快速幂+二分】
任意门:http://poj.org/problem?id=3233 Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K To ...
- HDU 4549 (费马小定理+矩阵快速幂+二分快速幂)
M斐波那契数列 Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u Submit Statu ...
随机推荐
- gcd和拓展gcd算法
gcd算法是用来求两个数最大公约数的算法,他是依靠辗转相除(中国好像叫辗转相减)法来求两个数的最大公约数,别的地方也有很多介绍不做过多赘述,主要提供代码供自己参考. gcd(int a,int b) ...
- JS数组的forEach方法(兼容所有浏览器)
//->自己在内置类的原型上扩展一个myForEach来处理forEach不兼容的问题//callBack:回调函数,遍历数组中的一项,就要执行一次callBack//context:改变cal ...
- Powershell Remove "Limited Access" - 金大昊(jindahao)
对于有多级web获取getlist会报错:Exception calling “GetList” with “1” argument $SPWeb = Get-SPWeb -Identity http ...
- onWindowFocusChanged
这个onWindowFocusChanged指的是这个Activity得到或者失去焦点的时候 就会call. 也就是说 如果你想要做一个Activity一加载完毕,就触发什么的话 完全可以用这个!!! ...
- Android项目实战(十六):QQ空间实现(一)—— 展示说说中的评论内容并有相应点击事件
大家都玩QQ空间客户端,对于每一个说说,我们都可以评论,那么,对于某一条评论: 白雪公主 回复 小矮人 : 你们好啊~ 我们来分析一下: .QQ空间允许我们 点击 回复人和被回复人的名字就可以进入对于 ...
- Android 文件访问权限的四种模式
Linux文件的访问权限* 在Android中,每一个应用是一个独立的用户* drwxrwxrwx* 第1位:d表示文件夹,-表示文件* 第2-4位:rwx,表示这个文件的拥有者(创建这个文件的应用) ...
- 【原】画流程图工具visio使用技巧汇总
最近写论文需要画不少流程图,有两种选择,一是word, 二是visio.原先一直用word画,效果也还可以,但是每个部件画完后为了便于适应排版变动,需要将需要的模块按下ctrl逐个点击选中后进行组合. ...
- 全球最低功耗蓝牙单芯片DA14580的软件体系 -RW内核和消息处理机制
上一篇文章<蓝牙单芯片DA14580的硬件架构和低功耗>阐述了DA14580的硬件架构和低功耗的工作原理.本文文章阐述该平台的软件体系,并着重分析消息事件的处理机制. 一.DA14580S ...
- Mac下安装Django
用到一个Python写的后台服务,需要用到Django,参考Django安装文档,配置过程如下: 1.下载一个用来安装和管理Python包的工具“pip”; 2.下载完成后,运行安装脚本,注意需要管理 ...
- 实验:传输层:UDP协议 学习笔记
一.传输层协议 从之前介绍的网络层协议来看,通信的两端是两台主机,IP数据报首部就标明了这两台主机的IP地址.但是从传输层来看,是发送方主机中的一个进程与接收方主机中的一个进程在交换数据,因此,严格地 ...