BZOJ3231: [Sdoi2008]递归数列

Description

一个由自然数组成的数列按下式定义:
对于i <= kai = bi
对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai-k
其中bj和 cj (1<=j<=k)是给定的自然数。写一个程序,给定自然数m <= n, 计算am + am+1 + am+2 + ... + an, 并输出它除以给定自然数p的余数的值。

Input

由四行组成。
第一行是一个自然数k
第二行包含k个自然数b1, b2,...,bk
第三行包含k个自然数c1, c2,...,ck
第四行包含三个自然数mnp

Output

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

Sample Input

2
1 1
1 1
2 10 1000003

Sample Output

142

HINT

对于100%的测试数据:
1<= k<=15
1 <= m <= n <= 1018


题解Here!

矩阵快速幂的沙茶题。
设$Ans(l,r)=\sum_{i=l}^ra_i$。
差一下分:$Ans(l,r)=Ans(1,r)-Ans(1,l-1)$
这种题只要构造出矩阵就万事大吉了。
我们很容易想到把$a_1,a_2,a_3,...,a_k$全部放到矩阵中。
但是求和怎么办?
没事,一并放到矩阵中。
设$sum(x)=\sum_{i=1}^xa_i$。
有这个式子:$$sum(x+1)=sum(x)+a_{x+1}=sum(x)+c_1\times a_{x}+c_2\times a_{x-1}+...+c_k\times a_{x-k+1}$$
所以我们构造出矩阵长这个样:$$\left[\begin{array}{}0&0&0&...&0&c_k&c_k\\1&0&0&...&0&c_{k-1}&c_{k-1}\\0&1&0&...&0&c_{k-2}&c_{k-2}\\0&0&1&...&0&c_{k-3}&c_{k-3}\\&&&......\\0&0&0&...&1&c_1&c_1\\0&0&0&...&0&0&1\end{array}\right]$$
最初的矩阵就是这样:$$\left[\begin{array}{}a_1&a_2&a_3&...&a_k&sum(k)\end{array}\right]$$
而$a_i=b_i,i\in [1,k]$。
然后就可以愉快地跑矩阵快速幂了。
附代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#define MAXN 20
using namespace std;
long long n,m,p,k;
long long b[MAXN],c[MAXN],sum[MAXN];
struct node{
long long val[MAXN][MAXN];
node(){
for(int i=0;i<=19;i++)
for(int j=0;j<=19;j++)
val[i][j]=0;
}
friend node operator *(node x,node y){
node ret;
for(int i=1;i<=k+1;i++)
for(int j=1;j<=k+1;j++){
ret.val[i][j]=0;
for(int l=1;l<=k+1;l++){
ret.val[i][j]+=x.val[i][l]*y.val[l][j]%p;
ret.val[i][j]%=p;
}
}
return ret;
}
friend node operator ^(node x,long long w){
node s;
for(int i=1;i<=k+1;i++)s.val[i][i]=1;
while(w){
if(w&1)s=s*x;
x=x*x;
w>>=1;
}
return s;
}
}a[3];
inline long long read(){
long long date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
long long solve(long long x,int id){
if(x<=k)return sum[x];
node ans;
for(int i=1;i<=k;i++)ans.val[1][i]=b[i];
ans.val[1][k+1]=sum[k];
ans=ans*(a[id]^(x-k));
return ans.val[1][k+1]%p;
}
void work(){
long long ans1=solve(n,1),ans2=solve(m-1,2);
printf("%lld\n",(ans1-ans2+p)%p);
}
void init(){
k=read();
sum[0]=0;
for(int i=1;i<=k;i++){
b[i]=read();
sum[i]=sum[i-1]+b[i];
}
for(int i=1;i<=k;i++)c[i]=read();
m=read();n=read();p=read();
a[1].val[k+1][k+1]=a[2].val[k+1][k+1]=1;
for(int i=1;i<k;i++)a[1].val[i+1][i]=a[2].val[i+1][i]=1;
for(int i=1;i<=k;i++)a[1].val[i][k]=a[1].val[i][k+1]=a[2].val[i][k]=a[2].val[i][k+1]=c[k-i+1];
}
int main(){
init();
work();
return 0;
}

BZOJ3231: [Sdoi2008]递归数列的更多相关文章

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

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

  2. BZOJ-3231 [SDOI2008]递归数列

    转成矩阵连乘后,矩阵快速幂加速解决. 一开始没把需要longlong的变量补全..而且没初始化2333 #include <cstdlib> #include <cstdio> ...

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

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

  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. P2461 [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. VS debug调试方法

    F5 开始调试,执行到断点 Shift + F5 停止调试 F9 在光标所在行添加断点 Shift + F9 QuickWatch Shift Ctrl F9 delete all 断点 F10 单步 ...

  2. DOS底下常用命令

    DOS底下常用命令: dir (directory) :列出当前目录下的文件以及文件夹 md (make directory): 创建目录 rd (remove directory):删除目录 cd ...

  3. datetimepicker[jquery-ui]时间控件的三种初始化方法

    1.只显示年月日 $( ".datepicker").datepicker({ needDay:true, changeMonth: true, //显示月份 changeYear ...

  4. Java 界面编程【03】事件监听

    当你把界面都设计好了,总需要添加相应的执行动作给组件,在JAVA中有相应的时间处理机制,叫做“监听器”,给组件添加相应执行动作的过程叫做“注册”,其中的“监听器”是一个接口,里面包含了相应的执行函数, ...

  5. 2017 ACM-ICPC 北京区域赛记录

    ------------------------------------------------------------------------------ 出发日 拖着一个大箱子走是真的累. 下午三 ...

  6. 轻量级Web渗透测试工具jSQL

    轻量级Web渗透测试工具jSQL jSQL是Kali集成的一款轻量级的Web渗透测试工具.最初该工具主要实施SQL注入,后来增加更多的功能,扩展形成一个综合性的Web渗透测试工具.Kali提供的版本较 ...

  7. logging模块详解以及常见代码

    1.在django中获取客户端IP地址: if 'HTTP_X_FORWARDED_FOR' in request.META: ip = request.META['HTTP_X_FORWARDED_ ...

  8. vs code theme Seti monokai

    http://www.jianshu.com/p/80e983201f86 Seti-UI主题是一款极具传奇色彩的主题

  9. Hibernate操作Blob数据

      首先看数据库.数据库中新建一个BlobTable表,表中有两个字段,一个id(主键)一个picture字段是Blob类型字段.然后使用Hibernate向该数据库中写入和读取数据 在POJO类中p ...

  10. Mybatis分页插件-PageHelper的使用

    转载:http://blog.csdn.net/u012728960/article/details/50791343 Mybatis分页插件-PageHelper的使用 怎样配置mybatis这里就 ...