【题解】递归数列

【题解】递归数列"题目链接"题目大意:给定序列迭代规则,求一段的序列和。特点是要求的序列很长。Solution观察到,由于是求和,我们可以想到前缀和的思想。也就是说,对于求$\sum_{i=

大家好,又见面了,我是你们的朋友全栈君。

题目链接

题目大意:给定序列迭代规则,求一段的序列和。特点是要求的序列很长。

Solution#

观察到,由于是求和,我们可以想到前缀和的思想。也就是说,对于求\(\sum_{i=m}^n a_i\),我们只需要求\(\sum_{i=1}^{m-1}a_i\)\(\sum_{i=1}^n a_i\),然后做差即可。

注意到\(n,m\)的范围,我们线性递推是不现实的。于是我们可以考虑矩阵快速幂。

考虑维护\(k+1\)个值。维护\(k\)个序列基本值,以及一个求和值。我们根据\(k\)个信息推出下一个信息。观察到\(k\)的范围,所以是可以做的。

构造矩阵比较简单。注意一下\(c\)的位置,是倒序的。

由于我们一次维护的是\(k\)个值,所以,如果我们要求\(pos\),则我们求出转移矩阵的\(pos-k\)次方就可以求出。

两次矩阵快速幂加上前缀和思想,这题做完了。

#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
ll n,m,p,s,ss[16],Ans,sss;
inline ll add(ll x,ll y){return (x%p+y%p)%p;}
inline ll mul(ll x,ll y){return (x%p*y%p)%p;}
inline ll del(ll x,ll y){return x-y<0?x+p-y:x-y;}
int k,b[16],c[16];
struct Mat{
	ll A[17][17];
	Mat(){memset(A,0,sizeof(A));}
	Mat operator*(const Mat&B)const{
		Mat res;
		for(int i=1;i<=k+1;++i)
			for(int j=1;j<=k+1;++j)
				for(int l=1;l<=k+1;++l)
					res.A[i][j]=add(res.A[i][j],mul(A[i][l],B.A[l][j]));
		return res;
	}
}w,s1,A2,A1;
inline void Init(Mat &x){for(int i=1;i<=k+1;++i)x.A[i][i]=1;}
Mat qpow(Mat st,ll b){
	Mat c;
	Init(c);
	while(b){
		if(b&1)c=c*st;
		b>>=1;st=st*st;
	}
	return c*s1;
}
signed main(){
	scanf("%lld",&k);
	for(int i=1;i<=k;++i)scanf("%lld",&b[i]);
	for(int i=1;i<=k;++i)scanf("%lld",&c[i]);
	scanf("%lld%lld%lld",&m,&n,&p);
	for(int i=1;i<=k;++i)ss[i]=add(ss[i-1],(ll)b[i]);
	for(int i=1;i<=k;++i)s1.A[i][1]=b[i];
	s1.A[k+1][1]=ss[k];
	for(int i=1;i<k;++i)w.A[i][i+1]=1;
	for(int i=1;i<=k;++i)w.A[k][i]=c[k-i+1],w.A[k+1][i]=c[k-i+1];
	w.A[k+1][k+1]=1;
	if(m-1>=k)A1=qpow(w,m-1-k);
	else A1.A[k+1][1]=ss[m-1];
	if(n>=k)A2=qpow(w,n-k);
	else A2.A[k+1][1]=ss[n];
	Ans=del(A2.A[k+1][1],A1.A[k+1][1]);
	printf("%lld\n",Ans);
	return 0;
} 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/155600.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 三次B样条曲线拟合算法

    三次B样条曲线拟合算法三次B样条曲线方程B样条曲线分为近似拟合和插值拟合,所谓近似拟合就是不过特征点,而插值拟合就是通过特征点,但是插值拟合需要经过反算得到控制点再拟合出过特征点的B样条曲线方程。这里会一次介绍两种拟合算法。首先介绍B样条的曲线方程。B样条曲线的总方程为:P(t)=∑ni=0PiFi,k(t)P(t)=\sum_{i=0}^{n}P_{i}F_{i,k}(t)(1)其中PiP_i是控制曲

    2022年6月18日
    28
  • 归并排序 详解「建议收藏」

    归并排序 详解「建议收藏」注:内容,图片来自于慕课网liuyubobobo老师的课程。算法复杂度:O(nlogn);也许有很多同学说,原来也学过很多O(n^2)或者O(n^3)的排序算法,有的可能优化一下能到O(n)的时间复杂度,但是在计算机中都是很快的执行完了,没有看出来算法优化的步骤,那么我想说有可能是你当时使用的测试用例太小了,我们可以简单的做一下比较:当数据量很大的时候nlogn的优势将会比…

    2022年8月12日
    6
  • 网页跳转qq聊天代码_html全屏代码

    网页跳转qq聊天代码_html全屏代码偶尔从某地得到我去看了看,果然可以但是又想了想他是怎么样和TENCENT数据库连接的呢?呵呵~自己做一个吧!原代码如下,自己有PHP空间的话,你也可以提供QQ在线的js代码服务了!连接代码把下面的代码保存成PHP文件就可以了!我想他也是连接别人的数据吧~那我也连接一下他的http://www.gaodaima.com/45503.html让你拥有自己的QQ在线显示代码(又是转_php$file=f…

    2022年10月17日
    4
  • c#Parallel.ForEach控制线程数量

    c#Parallel.ForEach控制线程数量List<int>listI=newList<int>();for(inti=0;i<1000;i++){listI.Add(i);}ParallelOptionsoptions=newParallelOptions();option..

    2022年7月19日
    15
  • idea2021年最新永久激活码【在线注册码/序列号/破解码】

    idea2021年最新永久激活码【在线注册码/序列号/破解码】,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月19日
    53
  • python菜鸟踩坑系列-pika版本带来的问题

    python菜鸟踩坑系列-pika版本带来的问题

    2021年5月16日
    211

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号