题目描述

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

对于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. idea配置SOLServer错误解决记录

    1.错误信息:2019-03-26 13:32:41.205 ERROR 7828 --- [nio-8081-exec-1] c.alibaba.druid.filter.stat.StatFilt ...

  2. lua字符串类型

    Lua中字符串结构体的定义是: typedef union TString { L_Umaxalign dummy; /* ensures maximum alignment for strings ...

  3. InsertionSort 直接插入排序(java)

    排序思想: 相当于一堆数字,一开始先取出2个数排序,2个数排好序之后,再从一堆数字里面取一个数排序,直到结束伪代码: INSERTION_SORT(A) for j = 2 to A.length k ...

  4. PHP核心技术——反射

    反射: 反射指在PHP运行状态中,扩展分析PHP程序,导出或提取出关于类.方法.属性.参数等的详细信息,包括注释.这种动态获取信息以及动态调用对象方法的功能称为反射API class person{ ...

  5. Flink架构分析之资源分配

    Task Slot     Flink中每个真正执行任务的TaskManager都是一个JVM进程,其在多线程环境中执行一个或者多个子任务.为了控制一个JVM同时能运行的任务数量,flink引入了ta ...

  6. WebRTC入门

    什么是WebRTC? 众所周知,浏览器本身不支持相互之间直接建立信道进行通信,都是通过服务器进行中转.比如现在有两个客户端,甲和乙,他们俩想要通信,首先需要甲和服务器.乙和服务器之间建立信道.甲给乙发 ...

  7. 欧拉筛——$O(n)$复杂度的质数筛法

    欧拉筛法可以以\(O(n)\)的时间,空间复杂度求出\(1-n\)范围内的所有质数. 其核心思想是每个合数仅会被其最小的质因数筛去一次. See this website for more detai ...

  8. shutdown命令详解

    基础命令学习目录 原文链接:http://www.cnblogs.com/qlqwjy/p/7746364.html 我 们在操作Linux v/服务器的时候肯定会有需要重启系统,或者关闭系统等操作. ...

  9. Hadoop错误码速查

    经常遇到的exception是:PipeMapRed.waitOutputThreads(): subprocess failed with code N "OS error code 1: ...

  10. TFS任务预览

    不太熟悉TFS任务项的建立. 初步建立及按老师要求分配到个人的任务设置与时间安排如下: (长时间任务可由多人合作完成,具体根据情况迅速调整任务分配) 加上每人需要进行阅读前一小组的代码需要时间2*8= ...