模板:常系数齐次线性递推(线性代数、多项式)

所谓常系数齐次线性递推,就是系数为常数的齐次线性递推。

(逃)

前言

sto Asta orz!
又是一个名字高大上,实则小清新的算法!

解析

考虑一个 k 次的线性递推:
an=∑i=1kfian−ia_n=\sum_{i=1}^kf_ia_{n-i}an=i=1kfiani
不断的把高次的项按照定义式拆成低次项,最终必然可以写成 ∑i=0k−1piai\sum_{i=0}^{k-1}p_ia_ii=0k1piai 的形式。
以最常见的斐波拉契为例:f5=f4+f3=2f3+f2=3f2+2f1=5f1+3f0f_5=f_4+f_3=2f_3+f_2=3f_2+2f_1=5f_1+3f_0f5=f4+f3=2f3+f2=3f2+2f1=5f1+3f0
然后带入 a0...k−1a_{0...k-1}a0...k1 的值计算即可。

注意到,我们分解高次项的过程,其实在本质上也就等价于令 xnx^nxn 不断向多项式 xk−f1xk−1−f2xk−2−...−fkx0x^k-f_1x^{k-1}-f_2x^{k-2}-...-f_kx^0xkf1xk1f2xk2...fkx0 取模的过程。
既然如此,我们就可以直接使用类似于快速幂的方法,不断把 xxx 平方并向上述的多项式取模即可。
暴力取模 O(k2log⁡n)O(k^2\log n)O(k2logn),使用多项式科技可以做到 O(klog⁡klog⁡n)O(k\log k\log n)O(klogklogn)

代码

(过度封装非常严重,常数极大。)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
inline ll read() {ll x(0),f(1);char c=getchar();while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
const int N=2e5+100;
const int mod=998244353;
int n,m,k;
inline ll ksm(ll x,ll k){ll res=1;while(k){if(k&1) res=res*x%mod;x=x*x%mod;k>>=1;}return res;
}
int niv2=ksm(2,mod-2);
int r[N];
void init(int n,int &lim){lim=1;int L=0;while(lim<n) lim<<=1,L++;for(int i=1;i<lim;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(L-1));
}
void NTT(ll *x,int lim,int op){for(int i=0;i<lim;i++) if(i<r[i]) swap(x[i],x[r[i]]);for(int l=1;l<lim;l<<=1){ll w=ksm(3,(mod-1)/(l<<1));if(op==-1) w=ksm(w,mod-2);for(int st=0;st<lim;st+=(l<<1)){for(ll i=0,now=1;i<l;i++,now=now*w%mod){ll u=x[st+i],v=now*x[st+i+l]%mod;x[st+i]=u+v>=mod?u+v-mod:u+v;x[st+i+l]=u-v<0?u-v+mod:u-v;}}}if(op==-1){ll ni=ksm(lim,mod-2);for(int i=0;i<lim;i++) x[i]=x[i]*ni%mod;}return;
}
void copy(ll *a,ll *b,int n,int lim){assert(n<=lim);memcpy(a,b,sizeof(ll)*n);fill(a+n,a+lim,0);return;
}
void mul(ll *a,ll *b,ll *c,int n,int m){static ll u[N],v[N];static int lim;init(n+m-1,lim);copy(u,a,n,lim);copy(v,b,m,lim);NTT(u,lim,1);NTT(v,lim,1);for(int i=0;i<lim;i++) c[i]=u[i]*v[i]%mod;NTT(c,lim,-1);//for(int i=0;i<n+m-1;i++) printf("%lld ",c[i]);putchar('\n');//putchar('\n');return;
}
void inv(ll *h,ll *f,int n){static ll t1[N],t2[N];static int lim;if(n==1){f[0]=ksm(h[0],mod-2);return;}inv(h,f,(n+1)>>1);init(n<<1,lim);fill(f+((n+1)>>1),f+lim,0);copy(t1,f,n,lim);copy(t2,h,n,lim);NTT(t1,lim,1);NTT(t2,lim,1);for(int i=0;i<lim;i++) t1[i]=(2*t1[i]-t1[i]*t1[i]%mod*t2[i]%mod+mod)%mod;NTT(t1,lim,-1);memcpy(f,t1,sizeof(ll)*n);return;
}
void chu(ll *f,ll *g,ll *q,ll *r,int n,int m){static ll F[N],G[N],ff[N],gg[N],Q[N],tmp[N];static int lim;--n;--m;init(n+n,lim);copy(F,f,n+1,lim);copy(ff,f,n+1,lim);copy(G,g,m+1,lim);copy(gg,g,m+1,lim);reverse(F,F+1+n);reverse(G,G+1+m);inv(G,tmp,n-m+1);mul(tmp,F,Q,n-m+1,n-m+1);reverse(Q,Q+n-m+1);//fill(Q+n-m+1,Q+n+1,0);for(int i=n-m+1;i<=n;i++) Q[i]=0;copy(q,Q,n-m+1,lim);mul(Q,gg,tmp,n+1,n+1);for(int i=0;i<n;i++) r[i]=(ff[i]+mod-tmp[i])%mod;return;
}ll F[N],G[N],Q[N],R[N];
void mul_mod(ll *x,ll *y,ll *Mod,int n){static ll t1[N],t2[N],t[N];static int lim;init(n+n,lim);copy(t1,x,n,lim);copy(t2,y,n,lim);mul(t1,t2,t,n,n);chu(t,Mod,t1,t,2*n-1,n+1);memcpy(x,t,sizeof(t));
}
ll LinearRecurrence(ll *a,ll *ff,int k,int n){static ll res[N],tmp[N],f[N];memset(tmp,0,sizeof(ll)*(k*2+5));memset(res,0,sizeof(ll)*(k*2+5));for(int i=0;i<k;i++) f[i]=(mod-ff[k-i])%mod;f[k]=1;tmp[1]=1;res[0]=1;while(n){if(n&1){     mul_mod(res,tmp,f,k);}mul_mod(tmp,tmp,f,k);n>>=1;}ll ans(0);for(int i=0;i<k;i++) ans=(ans+a[i]*res[i])%mod;return ans;
}
ll f[N],a[N];
signed main() {
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn=read();k=read();for(int i=1;i<=k;i++) f[i]=(read()%mod+mod)%mod;for(int i=0;i<k;i++) a[i]=(read()%mod+mod)%mod;printf("%lld\n",LinearRecurrence(a,f,k,n));return 0;
}
/*3 12 3 3 11 1
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/316720.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2021牛客暑期多校训练营1

2021牛客暑期多校训练营1 题号题目知识点难度AAlice and Bob博弈论BBall Dropping计算几何签到CCut the TreeDDetermine the Photo Position签到EEscape along Water PipeFFind 3-friendly Integers真签到GGame of Swapping Numbers思维题&#xff0c;推导HHash FunctionFFT&a…

【无码专区12】子集和(背包dp)

此题已自我实现&#xff0c;但仍归于无码专区 本题在考场上就过了&#xff0c;所以难度并不高&#xff0c;发现性质即可。 problem 有 nnn 个正整数 a1,a2,...,ana_1,a_2,...,a_na1​,a2​,...,an​&#xff0c;他们的和为 mmm。你想对于其每一个子集 SSS&#xff0c;求出他…

Penguins

Penguins 题意&#xff1a; 有两个20*20的地图&#xff0c;有障碍物&#xff0c;两个地图各有一个小人&#xff0c;左侧地图的小人要从右下角走到右上角&#xff0c;右侧地图的小人要从左下角走到左上角&#xff0c;这两个小人是镜像移动的&#xff0c; 左侧小人右侧小人左移…

盲盒(随机概率 + 最大公约数)

盲盒problemsolutioncodeproblem 有 2n2n2n 个盲盒&#xff0c;每个盲盒有一个惊喜值 aia_iai​。 打开恰好 nnn 个盲盒&#xff0c;获得的惊喜值为这些盲盒惊喜值的最大公约数。 求能获得的最大惊喜值。 n≤1e5,ai≤1e12n\le 1e5,a_i\le 1e12n≤1e5,ai​≤1e12。 solution…

P5354 [Ynoi2017] 由乃的 OJ(树剖、位运算)

前言 当暴力思路与题解中的“暴力”不同时&#xff0c;继续想优化往往就渐行渐远了… 所以当没有头绪时&#xff0c;要勇于跳出原有的转化&#xff01; 这种位运算类型的优化似乎始终不在我的寄存器中…需要加强&#xff01; 解析 不难想到按位考虑的 O(nklog⁡2n)O(nk\log…

在 .NET Core 中运行 JavaScript

一.前言在 .NET Framework 时&#xff0c;我们可以通过V8.NET等组件来运行 JavaScript&#xff0c;不过目前我看了好几个开源组件包括V8.NET都还不支持 .NET Core &#xff0c;我们如何在 .NET Core 中运行 JavaScript 呢&#xff0c;答案是使用 NodeServices。关于为何有在 .N…

I love exam HDU - 6968

I love exam HDU - 6968 题意&#xff1a; 有n个考试科目&#xff0c;现在有m套复习资料&#xff0c;每套复习资料需要花费wi天使用&#xff0c;用完提升ci的分数&#xff0c;现在还有t天复习时间&#xff0c;挂科数目不能超过p&#xff0c;问所有达到的最大分数 题解&#…

[CF1442 D] Sum(分治优化dp + 结论)

CF1442D Sumproblemsolutioncodeproblem luogu翻译 solution 部分分做法&#xff0c;预处理每组前缀和&#xff0c;暴力背包 dpdpdp 转移&#xff1a;dpi,jmax⁡{dpi−1,j−ksumi(k)∣0≤k≤l[i]}dp_{i,j}\max\Big\{dp_{i-1,j-k}sum_i(k)\ \Big|\ 0\le k\le l[i]\Big\}dpi,j…

P4338 [ZJOI2018]历史(树剖)(暴力)

前言 有点懊恼的一个题… 并没有其他那些ZJOI那么毒瘤&#xff0c;看出了关键结论&#xff0c;但最后维护卡在log条虚边的伞兵性质上了。 解析 第一眼&#xff1a;感觉根本不可做啊。 冷静一下&#xff0c;既然它还变态的带修&#xff0c;一定是可以转化成比较形式化的东西的…

Named Volume 在 MySQL 数据持久化上的基本应用

原文作者&#xff1a;春哥非常感谢春哥的投稿&#xff0c;同时也有一些感慨。初识春哥时&#xff0c;春哥是美术设计大咖。后不久&#xff0c;创业并致力于游戏开发&#xff0c;已有3年。从Unity3D到IOS&#xff08;Swift&#xff09;开发&#xff0c;从前端开发到后端以及容器…

Codeforces Round #723 (Div. 2)

Codeforces Round #723 (Div. 2) 题号题目知识点AMean Inequality签到BI Hate 1111思维CPotions (Easy Version)思维C1Potions (Hard Version)思维DKill Anton思维逆序对EOolimry and Suffix ArrayFMedian Queries CF1526A Mean Inequality 题意&#xff1a; 给你一个序列a&…

[AtCoder Regular Contest 060] E - Tak and Hotels

AT2039 [ARC060C] 高橋君とホテル / Tak and Hotelsproblemsolution - 分块code - 分块solution - 倍增code - 倍增problem luogu翻译 solution - 分块 肯定刚开始&#xff0c;我们很想暴力跳过去。事件复杂度取决于数据。 肯定不做把头拿给别人砍的事 这种跳法&#xff0…

模板:珂朵莉树

所谓珂朵莉树&#xff0c;就是珂朵莉发明的树。 &#xff08;逃 前言 在数据随机且带区间推平操作时适用&#xff0c;此时所有操作的期望颜色段数都是 O(log⁡n)O(\log n)O(logn) 的&#xff0c;可以使用暴力解决即可。 暴力即优雅。 解析 利用 set 维护颜色段&#xff1a;…

.Netcore 2.0 Ocelot Api网关教程(7)- 限流

本文介绍Ocelot中的限流&#xff0c;限流允许Api网关控制一段时间内特定api的总访问次数。限流的使用非常简单&#xff0c;只需要添加配置即可。1、添加限流修改 configuration.json 配置文件&#xff0c;对 UpstreamPathTemplate 为 /webapib/values 的配置修改如下&#xff1…

cf1526 C Potions

cf1526 C Potions 题意&#xff1a; n个药剂&#xff0c;每个药剂可以加/减能量&#xff0c;一开始能量为0&#xff0c;从左往右开始进行&#xff0c;全程能量不为负&#xff0c;问最多可以使用几个药剂 本题有简单(n<2000),困难模式(n≤200000) 题解&#xff1a; 简单题…

[CF 526 F] Pudding Monsters(单调栈 + 线段树)

CF526F Pudding Monstersproblemsolutioncodeproblem luogu翻译 solution observation &#xff1a;每行每列恰好有一个棋子&#xff0c;所以如果一段区间 [l,r][l,r][l,r] 会被某个 kkk 统计&#xff0c;当且仅当这个区间内棋子纵坐标 ymax−ymin1r−l1y_{max}-y_{min}1r-l…

微信开发必看,使用.Net Core 开发微信跨平台应用

.NET Core 是一个开源通用的开发框架&#xff0c;源码由微软官方和社区共同支持。支持跨平台&#xff0c;即支持在 Window&#xff0c;macOS&#xff0c;Linux 等系统上的开发和部署&#xff0c;并且可以在硬件设备&#xff0c;云服务&#xff0c;和嵌入式/物联网方案中进行使用…

P5590 赛车游戏(差分约束)

前言 9月做的题现在不会了&#xff1f;&#xff1f;&#xff1f; 越学越拉了属于是。 解析 设 disxdis_xdisx​ 表示 1-x 的最小距离&#xff0c;那么一条 u->v 的边的边权就是 disv−disudis_v-dis_udisv​−disu​。 差分约束即可。 挂掉的坑点&#xff1a;只需要考虑…

CF1526 D. Kill Anton

CF1526 D. Kill Anton 题意&#xff1a; 给你一个由’A’,‘N’.‘T’,O’四个字符组成的字符串b&#xff0c;现在要求你改变b的顺序得到a&#xff0c;使得a通过移动回到b的步数最多。 每次移动只能移动相邻两项 题解&#xff1a; 官方题解说&#xff1a;最佳情况为相同字符…

[luogu P4198] 楼房重建(线段树 + 思维)

luogu 楼房重建problemsolutioncodeproblem 洛谷链接 solution 非常巧妙的一道题&#xff0c;对线段树的运用很灵活。 显然这个与原点的连线可以想到将每个点转化为与原点连线形成的直线斜率。 答案其实就是&#xff1a;从第一个点开始选&#xff0c;后一个斜率比前面大的…