题目描述

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

对于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. TPO-21 C2 Which elective courses to take

    /* 加粗:语音部分 * 红色:单词部分 * 斜体:语法部分 * 下划线:信号词/句 */ 第 1 段 1.Listen to a conversation between a student and ...

  2. 特效Shader对雾的处理

    RFX4_Particle.shader案例 #ifdef BlendAdd UNITY_APPLY_FOG_COLOR(i.fogCoord, res, half4(0,0,0,0)); #endi ...

  3. Tensorflow张量的形状表示方法

    对输入或输出而言: 一个张量的形状为a x b x c x d,实际写出这个张量时: 最外层括号[…]表示这个是一个张量,无别的意义! 次外层括号有a个,表示这个张量里有a个样本 再往内的括号有b个, ...

  4. Datawhale MySQL 训练营 Task1:MySQL 安装与数据库基础

    安装 平台 Windows X64; MySQL: 直接去 MySQL 官网 下载:点击即可安装:安装过程中可能会要求 python3.7; 可以去安装一个 python3.7; 可视化工具:Navi ...

  5. C++ 单例模式总结与剖析

    目录 C++ 单例模式总结与剖析 一.什么是单例 二.C++单例的实现 2.1 基础要点 2.2 C++ 实现单例的几种方式 2.3 单例的模板 三.何时应该使用或者不使用单例 反对单例的理由 参考文 ...

  6. Python中格式化format()方法详解

    Python中格式化format()方法详解 Python中格式化输出字符串使用format()函数, 字符串即类, 可以使用方法; Python是完全面向对象的语言, 任何东西都是对象; 字符串的参 ...

  7. 用 Delphi 7 实现基于 FFMS2 的视频转 GIF 工具 [原创]

    儿子经常要把自拍的视频(ts格式)转成表情包,下载了几个工具都不大好用,更多的还要收费.那就想自己写一个吧,没想到这一下断断续续地,居然 3 个月过去了.现在总算弄出个作品来了,结个贴吧.唉,天资愚钝 ...

  8. 用Solidity在Truffle上构建一个HelloWorld智能合约

    原文地址:石匠的blog Truffle的环境安装在前文已经整理,这次用Solidity在Truffle写一个HelloWorld以太坊智能合约,并在testrpc上进行测试.当前的软件版本信息如下: ...

  9. ossec安装

    安装 安装要求 对于Unix系统来说,OSSEC只需要GNU的make.gcc和libc.推荐使用OpenSSL,但仅属于一个可选项.而且,通常您只需在一个系统上做编译操作,然后将二进制程序复制到其他 ...

  10. jumpserver安装与部署

    1.简介 Jumpserver 是一款由Python编写开源的跳板机(堡垒机)系统,实现了跳板机应有的功能.基于ssh协议来管理,客户端无需安装agent.特点:  完全开源,GPL授权   Pyth ...