题目描述

一个由自然数组成的数列按下式定义:

对于i <= k:ai = bi

对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai-k

其中bj 和 cj (1<=j<=k)是给定的自然数。写一个程序,给定自然数m <= n, 计算am + am+1 + am+2 + ... + an, 并输出它除以给定自然数p的余数的值。

输入输出格式

输入格式:

输入文件spp.in由四行组成。

第一行是一个自然数k。

第二行包含k个自然数b1, b2,...,bk。

第三行包含k个自然数c1, c2,...,ck。

第四行包含三个自然数m, n, p。

输出格式:

输出文件spp.out仅包含一行:一个正整数,表示(am + am+1 + am+2 + ... + an) mod p的值。

输入输出样例

输入样例#1:

2
1 1
1 1
2 10 1000003
输出样例#1:

142

说明

对于100%的测试数据:

1<= k <=15

1 <= m <= n <= 1018

对于20%的测试数据:

1<= k <=15

1 <= m <= n <= 106

对于30%的测试数据:

k=1 1 <= m <= n <= 1018

对于所有测试数据:

0<= b1, b2,... bk, c1, c2,..., ck<=109

1 <= p <= 108

Solution:

  本题矩阵快速幂。

  求$\sum_\limits{i=m}^{i\leq n}a_i$,可以转化为前缀和相减$s_n-s_{m-1}$。

  那么我们需要快速求出$s_i$,我们发现$a_i$只与前$k$个$a$值有关,于是我们可以构建一个$(k+1)*(k+1)$的矩阵,存下前$k$个$a$值和当前的前缀和$s$。

  转移矩阵的构造就补$1$并依次填好$c$值就好了。

代码:

/*Code by 520 -- 10.11*/
#include<bits/stdc++.h>
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const int N=;
struct matrix{
int r,c;ll a[N][N];
il void clr(){memset(a,,sizeof(a));}
}ans,tp;
ll n,m,k,mod,b[N],c[N],s[N]; il matrix mul(matrix x,matrix y){
matrix tp; tp.clr();
tp.r=x.r,tp.c=y.c;
For(i,,x.r-) For(j,,y.c-) For(k,,x.c-)
tp.a[i][j]=(tp.a[i][j]+x.a[i][k]*y.a[k][j]%mod)%mod;
return tp;
} int main(){
ios::sync_with_stdio();
cin>>k;
For(i,,k) cin>>b[i],s[i]=(s[i-]+b[i]);
For(i,,k) cin>>c[i];
cin>>n>>m>>mod; ll tot=;
if(m<=k) cout<<(s[m]-s[n-])%mod,exit();
ans.r=,ans.c=k+; tp.r=tp.c=k+; ans.clr(),tp.clr();
For(i,,k-) ans.a[][i]=b[i+]%mod; ans.a[][k]=s[k]%mod;
For(i,,k-) tp.a[i][i-]=,tp.a[i][k-]=tp.a[i][k]=c[k-i]%mod;
tp.a[][k-]=tp.a[][k]=c[k]%mod;tp.a[k][k]=;
if(n<=k) tot-=s[n-]%mod;
else {
n-=k+;
while(n){
if(n&) ans=mul(ans,tp);
n>>=,tp=mul(tp,tp);
}
tot-=ans.a[][k];
}
ans.r=,ans.c=k+; tp.r=tp.c=k+; ans.clr(),tp.clr();
For(i,,k-) ans.a[][i]=b[i+]%mod; ans.a[][k]=s[k]%mod;
For(i,,k-) tp.a[i][i-]=,tp.a[i][k-]=tp.a[i][k]=c[k-i]%mod;
tp.a[][k-]=tp.a[][k]=c[k]%mod;tp.a[k][k]=;
m-=k;
while(m){
if(m&) ans=mul(ans,tp);
m>>=,tp=mul(tp,tp);
}
tot=(tot+mod+ans.a[][k])%mod;
cout<<tot;
return ;
}
 
 
 

P2461 [SDOI2008]递归数列的更多相关文章

  1. P2461 [SDOI2008]递归数列 矩阵乘法+构造

    还好$QwQ$ 思路:矩阵快速幂 提交:1次 题解: 如图: 注意$n,m$如果小于$k$就不要快速幂了,直接算就行... #include<cstdio> #include<ios ...

  2. BZOJ 3231: [Sdoi2008]递归数列( 矩阵快速幂 )

    矩阵乘法裸题..差分一下然后用矩阵乘法+快速幂就可以了. ----------------------------------------------------------------------- ...

  3. BZOJ3231: [Sdoi2008]递归数列

    BZOJ3231: [Sdoi2008]递归数列 Description 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + ...

  4. BZOJ_3231_[Sdoi2008]递归数列_矩阵乘法

    BZOJ_3231_[Sdoi2008]递归数列_矩阵乘法 Description 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1a ...

  5. 开始玩矩阵了!先来一道入门题![SDOI2008]递归数列

    [SDOI2008]递归数列 题目描述 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + c ...

  6. [bzoj3231][SDOI2008]递归数列——矩阵乘法

    题目大意: 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai-k 其中bj和 cj ...

  7. 【bzoj3231】[Sdoi2008]递归数列 矩阵乘法+快速幂

    题目描述 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai-k 其中bj和 cj  ...

  8. [luogu2461 SDOI2008] 递归数列 (矩阵乘法)

    传送门 Description 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai- ...

  9. [SDOI2008]递归数列

    嘟嘟嘟 裸的矩阵快速幂,构造一个\((k + 1) * (k + 1)\)的矩阵,把sum[n]也放到矩阵里面就行了. #include<cstdio> #include<iostr ...

随机推荐

  1. 【轮子狂魔】抛弃IIS,打造个性的Web Server - WebAPI/Lua/MVC(附带源码)

    引言 此篇是<[轮子狂魔]抛弃IIS,向天借个HttpListener - 基础篇(附带源码)>的续篇,也可以说是提高篇,如果你对HttpListener不甚了解的话,建议先看下基础篇. ...

  2. Python中的dict字典的用法

    Python中的字典特点: 速度快,内部使用二分查找的方式 可以用来存储大量的关系型数据 字典是无序的 字典的定义方式: dic = dict(name =”zhangsan”,  age = 19) ...

  3. 在vsphere6.5启用Tesla K80

    基础环境: vsphere6.5 VMware vCenter6.5 宝德服务器2750S Tesla K80 0x01 选择主机,配置→硬件→PCI设备→添加K80显卡 注意:1.添加完显卡后,主机 ...

  4. PHPCMS 栏目添加字段和修改描述textarea变成fceditor编辑器

    一.添加字段方法: 1. 添加数据库字段:description1,添加位置:v9_catetory表 找到phpcms/moudles/admin/templates/category_add.tp ...

  5. centos7 --ngnix 常用命令:

    配置命令 随服务器启动 # systemctl enable nginx.service 重启 nginx 服务 # systemctl restart nginx.service 停止 nginx ...

  6. Netty源码分析第7章(编码器和写数据)---->第5节: Future和Promies

    Netty源码分析第七章: 编码器和写数据 第五节: Future和Promise Netty中的Future, 其实类似于jdk的Future, 用于异步获取执行结果 Promise则相当于一个被观 ...

  7. SQL-Server collation, what is it and how to change db/column collation

    The thing about collations is that although database have it's own collation, every table, and every ...

  8. fsck命令详解

    基础命令学习目录首页 本文出自 “airfish2000” 博客,更多命令查看博客: http://airfish2000.blog.51cto.com/10829608/1880801   fsck ...

  9. pstree命令详解

    基础命令学习目录首页 pstree命令是用于查看进程树之间的关系,即哪个进程是父进程,哪个是子进程,可以清楚的看出来是谁创建了谁#pstree几个重要的参数:-A: 各进程树之间的连接以ASCII码字 ...

  10. Beta周王者荣耀交流协会第五次Scrum会议

    1. 立会照片 成员王超,高远博,冉华,王磊,王玉玲,任思佳,袁玥全部到齐. master:王磊 2. 时间跨度 2017年11月14日 19:00 — 19:50 ,总计50分钟. 3. 地点 一食 ...