【题解】递归数列

【题解】递归数列"题目链接"题目大意:给定序列迭代规则,求一段的序列和。特点是要求的序列很长。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)
上一篇 2022年7月2日 下午11:16
下一篇 2022年7月2日 下午11:16


相关推荐

  • pytorch MSELoss参数详解「建议收藏」

    pytorch MSELoss参数详解「建议收藏」pytorchMSELoss参数详解importtorchimportnumpyasnploss_fn=torch.nn.MSELoss(reduce=False,size_average=False)a=np.array([[1,2],[3,8]])b=np.array([[5,4],[6,2]])input=torch.autograd.Variable(to…

    2026年1月19日
    7
  • calico工作原理_Calico原理

    calico工作原理_Calico原理容器网络的解决方案跨节点的容器网络要解决两个问题 容器如何分配 IPflannel 设计了一种全局的网络地址分配机制 即使用 etcd 存储网段和节点之间的关系 然后 flannel 配置各个节点上的 Docker 或其他容器工具 只在分配到当前节点的网段里选择容器 IP 地址 这样就确保了 IP 地址分配的全局唯一性 容器 IP 地址如何路由 overlay 网络 vxlanudp 直接路由 host gateway 在 overl

    2026年3月19日
    2
  • 海康威视流媒体服务器配置心得

    海康威视流媒体服务器配置心得海康威视现在基本是各单位监控设备的首选 最近老大需要把单位的监控点给上级转发 命我配置一下 由于对流媒体服务器认识比较模糊 直觉觉得只需要对内网一台 PC 配置双网卡 再使用流媒体服务器进行转发就可以了 但是买了个 USB 网卡后 配置流媒体服务器时就卡壳了 查询了各种资料后发现了很大一个问题 nbsp nbsp nbsp nbsp nbsp nbsp nbsp 原来流媒体服务器只是用于平衡负载的 鸡肋 配置方法 以最

    2026年3月18日
    3
  • 风暴数码论坛教程--加入ROOT等文件及方法

    风暴数码论坛教程--加入ROOT等文件及方法加入 ROOT 等文件及方法 1 利用厨房进行添加进入厨房界面首先 选择第 2 项 进入如下界面 我们选择 F 完成后我们点 enter 继续 继续回到主界面选择 3 项 出现如下界面 选择 y 完成过后 厨房添加 ROOT 过程就算完成 2 手动添加 ROOT 权限首先我们准备 superuser apk sh su busybox 这几文件 把 superuser apk 放入 s

    2026年3月19日
    1
  • Android中Parcelable的原理和使用方法

    Android中Parcelable的原理和使用方法Parcelable 的简单介绍介绍 Parcelable 不得不先提一下 Serializable 接口 Serializable 是 Java 为我们提供的一个标准化的序列化接口 那什么是序列化呢 进行 Android 开发的时候 无法将对象的引用传给 Activities 或者 Fragments 我们需要将这些对象放到一个 Intent 或者 Bundle 里面 然后再传递 简单来说就是将对象转换为可以传输的二进制流 二进制序列 的过程 这样我们就可以通过序列化 转化为可以在网络传输或者保存到本地的流 序列 从而进行传

    2026年3月19日
    2
  • MFC第三课 多字节处理

    MFC第三课 多字节处理

    2022年3月6日
    45

发表回复

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

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