题意:给一个递推式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 --二分求和+矩阵快速幂的更多相关文章

  1. 【学术篇】SPOJ GEN Text Generator AC自动机+矩阵快速幂

    还有5天省选才开始点字符串这棵技能树是不是太晚了点... ~题目の传送门~ AC自动机不想讲了QAQ.其实很久以前是学过然后打过板子的, 但也仅限于打过板子了~ 之前莫名其妙学了一个指针版的但是好像不 ...

  2. poj3233 题解 矩阵乘法 矩阵快速幂

    题意:求S = A + A2 + A3 + … + Ak.(mod m) 这道题很明显可以用矩阵乘法,但是这道题的矩阵是分块矩阵, 分块矩阵概念如下:当一个矩阵A中的单位元素aij不是一个数值而是一个 ...

  3. POJ 3233 Matrix Power Series 矩阵快速幂+二分求和

    矩阵快速幂,请参照模板 http://www.cnblogs.com/pach/p/5978475.html 直接sum=A+A2+A3...+Ak这样累加肯定会超时,但是 sum=A+A2+...+ ...

  4. 2017 ECJTU ACM程序设计竞赛 矩阵快速幂+二分

    矩阵 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submission ...

  5. 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+...+ ...

  6. BZOJ.4180.字符串计数(后缀自动机 二分 矩阵快速幂/倍增Floyd)

    题目链接 先考虑 假设S确定,使构造S操作次数最小的方案应是:对T建SAM,S在SAM上匹配,如果有S的转移就转移,否则操作数++,回到根节点继续匹配S.即每次操作一定是一次极大匹配. 简单证明:假设 ...

  7. POJ3233:Matrix Power Series(矩阵快速幂+二分)

    http://poj.org/problem?id=3233 题目大意:给定矩阵A,求A + A^2 + A^3 + … + A^k的结果(两个矩阵相加就是对应位置分别相加).输出的数据mod m.k ...

  8. POJ 3233 Matrix Power Series 【经典矩阵快速幂+二分】

    任意门:http://poj.org/problem?id=3233 Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K To ...

  9. HDU 4549 (费马小定理+矩阵快速幂+二分快速幂)

    M斐波那契数列 Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Statu ...

随机推荐

  1. 字典集合Dictionary<K,V>和构造的应用==>>体检套餐项目

    效果 首先,我们先来准备我们需要的类 1.检查项目类 using System; using System.Collections.Generic; using System.Linq; using ...

  2. 探索HashMap实现原理及其在jdk8数据结构的改进

    因为网上已经太多的关于HashMap的相关文章了,为了避免大量重复,又由于网上关于java8的HashMap的相关文章比较少,至少我没有找到比较详细的.所以才有了本文. 本文主要的内容: 1.Hash ...

  3. 「C语言」C输出hello world!系统发生了什么?

    本篇文章全部摘抄自学长博客供以后学习: http://efraim.me/2015/12/05/tech-linux-2015-12-05/ 排版因与博客园编辑器不同而稍作修改. 输出hello wo ...

  4. JavaScript 之垃圾回收和内存管理

    JavaScript 具有自动垃圾收集机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存.而在 C 和 C++ 之类的语言中,开发人员的一项基本 ...

  5. RHEL7文件权限

    本文介绍Linux下的文件权限 操作系统为RHEL7.2_X86_64 可以从以下三种访问方式限制访问权限: 1 只允许用户自己访问 2 允许一个预先指定的用户组中的用户访问 3 允许系统中的任何用户 ...

  6. CSS重置样式表

    网页设计,让人最头疼的莫过于让页面兼容各大浏览器,准确些是兼容它们“默认”的CSS样式表.第一种方式 * {margin:0px; padding:0px;} 这行代码虽然简单,但却让网页解析太慢.于 ...

  7. 在Android Studio中用Gradle添加Robolectric

    我们用Robolectric测试的话需要在gradle中进行配置,国内的详细教程太过简易,而且很多是低版本下的配置方案.所以经过本人的仔细摸索,找到了现在高版本中的配置方案,主要还是参考了官网的配置教 ...

  8. android 内存泄露调试

    一.概述 1 二.Android(Java)中常见的容易引起内存泄漏的不良代码 1 (一) 查询数据库没有关闭游标 2 (二) 构造Adapter时,没有使用缓存的 convertView 3 (三) ...

  9. IT技术很好的视频网址

    1.华为工程师 带你实战C++ 2.vimoe,国外的,需要FQ哦.https://vimeo.com/85831438

  10. linux---文本编辑vi

    本文摘自:鸟哥的linux私房菜