当前位置: 首页 > news >正文

题解:P4723 【模板】常系数齐次线性递推

更差的阅读体验


BM 部分内容参考 OI-wiki 有关部分,致谢。

Bostan-Mori 算法

\([x^k] \frac{P(x)}{Q(x)}\)\(k\) 很大。

\[\begin{align} [x^k] \frac{P(x)}{Q(x)} &= [x^k] \frac{P(x) Q(-x)}{Q(x) Q(-x)}\nonumber \\ &= [x^k] \frac{F_0(x^2) + x F_1(x^2)}{G(x^2)} \nonumber \\ &= [x ^ {\lfloor k / 2 \rfloor}] \frac{F_{k \bmod 2}(x)}{G(x)} \nonumber \end{align}\]

注明一下:\(Q(x)\)\(Q(-x)\) 的卷积显然为偶函数,因此仅含有偶次项,我们将其表示成 \(G(x^2)\) 的形式。而我们记 \(F(x) = P(x)Q(-x) = F_0(x^2) + x F_1(x^2)\),其中 \(F_0, F_1\)\(F\) 拆分奇偶次项的结果。

可以看到,我们将原问题变为了 \(k\) 折半的子问题。对于每个 \(k\) 我们要求解卷积,只需要两次 NTT,不难做到 \(O(n \log n \log k)\)

参考实现在最后。

常系数齐次线性递推

\(a_n = \sum \limits_{i = 1} ^ k f_{i} a_{n-i}\)

有了 Bostan-Mori 算法,我们尝试构造 \(a_n = [x^n] \frac{P(x)}{Q(x)}\)

假设 \(A(x) = \sum_i a_i x^i\),那么 \(A(x)Q(x) = P(x)\)。由于 \(n\) 很大,取 \(P\) 的高位我们认为是 \(0\)

那么 \([x^n] A(x)Q(x) = 0\)。假设 \(Q\) 各项系数为 \(q\)。则有

\[\sum_{i = 0}^n a_i q_{n-i} = 0 \]

那么我们把 \(a_n\) 提取出来,等价于左右同除以 \(q_0\),也就是

\[a_n = - \sum_{i = 0}^{n - 1} \frac{q_{n - i}}{q_0} a_i \]

同理 \(q\) 的高位我们也认为是 \(0\),可以直接去掉。所以其实 \(i\) 是从 \(n - k\) 开始枚举,也就是

\[a_n = - \sum_{i = n - k}^{n - 1} \frac{q_{n - i}}{q_0} a_i \]

容易发现,我们构造 \(q_0 = -1, q_i = f_i\) 就可以得到题目给出的递推式子。

有了 \(Q\)\(P\) 可以看作 \(A\)\(Q\) 的卷积,一次 NTT 即可。

然后套用上述 Bostan-Mori 即可求解 \([x^n] \frac{P(x)}{Q(x)}\)。复杂度 \(O(k \log k \log n)\)


我的卷积板子实现得非常古早,用数组实现的。为了防止 NTT 后原多项式中出现不可名状得数值,我直接在卷积后把两个原多项式都清空了。所以有的数组要备份很多遍,代码显得比较丑陋,凑合看罢。

#include<bits/stdc++.h>
#define endl '\n'
#define N 1000006
using namespace std;
constexpr int MOD=998244353,G=3,invG=332748118;
int r[N];
int qpow(int x,int y)
{int ret=1;for(;y;y>>=1,x=1ll*x*x%MOD)if(y&1)ret=1ll*ret*x%MOD;return ret;
}
void NTT(int len,int *a,int opt)
{for(int i=0;i<len;i++)if(i<r[i])swap(a[i],a[r[i]]);for(int i=1;i<len;i<<=1){int tmp=i<<1,Wn=qpow(opt==1?G:invG,(MOD-1)/tmp);for(int j=0;j<len;j+=tmp){int w=1,x,y;for(int k=0;k<i;k++,w=1ll*w*Wn%MOD){x=a[j+k],y=1ll*w*a[i+j+k]%MOD;a[j+k]=(x+y)%MOD,a[i+j+k]=(x+MOD-y)%MOD;}}}
}
void mul(int n,int m,int *a,int *b,int *ans)
{int len=1,lg=0;while(len<n+m)len<<=1,lg++;for(int i=0;i<len;i++)r[i]=(r[i>>1]>>1)|((i&1)<<lg-1);NTT(len,a,1),NTT(len,b,1);for(int i=0;i<len;i++)a[i]=1ll*a[i]*b[i]%MOD;NTT(len,a,-1); int inv=qpow(len,MOD-2);for(int i=0;i<=len;i++)b[i]=ans[i]=0;for(int i=0;i<n+m;i++)ans[i]=1ll*a[i]*inv%MOD;for(int i=0;i<=len;i++)a[i]=0;
}
int _q[N],f[N],g[N];
int bostan_mori(int n,int m,int *p,int *q,int k)
{for(;k;k>>=1){for(int i=0;i<m;i++)_q[i]=q[i];for(int i=1;i<m;i+=2)_q[i]=(MOD-_q[i])%MOD;mul(n,m,p,_q,f);for(int i=0;i<m;i++)_q[i]=q[i];for(int i=1;i<m;i+=2)_q[i]=(MOD-_q[i])%MOD;mul(m,m,q,_q,g);int new_n=0,new_m=0;for(int i=k&1;i<n+m-1;i+=2)p[new_n++]=f[i];for(int i=0;i<m+m-1;i+=2)q[new_m++]=g[i];n=new_n,m=new_m;}if(!n||!m)return 0;return 1ll*p[0]*qpow(q[0],MOD-2)%MOD;
}
int n,k,q[N],qq[N],a[N],res[N];
main()
{scanf("%d%d",&n,&k),q[0]=qq[0]=MOD-1;for(int i=1;i<=k;i++)scanf("%d",&q[i]),qq[i]=q[i]=(q[i]%MOD+MOD)%MOD;for(int i=0;i<k;i++)scanf("%d",&a[i]),a[i]=(a[i]%MOD+MOD)%MOD;mul(k+1,k,q,a,res);for(int i=k;i<N;i++)res[i]=0;printf("%d\n",bostan_mori(k,k+1,res,qq,n));return 0;
}
http://www.jsqmd.com/news/406139/

相关文章:

  • Doris数据分片策略详解:提升大数据查询效率的关键
  • P2757 [国家集训队] 等差子序列
  • 深度解析GPT在AI原生应用领域的应用场景
  • AI写专著不再愁!专业工具详细解读,助你高效完成学术使命
  • 借助AI专著撰写神器!高效完成专著,节省大量时间精力
  • 格雷厄姆特价股票策略在高科技行业的应用挑战
  • 从技术到管理:AI应用架构师转型项目管理的方法论与心路历程
  • 全球股市估值与可再生能源并网技术的关系
  • 【电池】基于PMP算法的插电式混合动力车 能量优化控制策略附Matlab代码
  • 微博评论采集
  • 【电力系统】风力涡轮机控制的 velvet 半有理多项式 MPC算法附matlab代码
  • JavaScript 类型转换
  • 【电池】基于LPV模型预测控制方法和耦合电热模型的电池状态估计附matlab代码
  • Python 量化:技术、应用与未来趋势
  • FastAPI的Alembic踩坑记录:缺失历史迁移脚本如何保留数据重建版本控制
  • Bumble Android HFP漏洞利用PoC:智能设备蓝牙协议安全分析
  • 计算机毕业设计springboot学员课外任务自主分配管理系统 基于SpringBoot的高校学生课外实践任务智能调度平台 SpringBoot框架下学员第二课堂任务协同分配与追踪系统
  • 【控制】工业过程的容错线性参数 varying模型预测控制方案附matlab代码
  • 【车辆控制】基于考虑天气条件和路面坡度的电动汽车基于电压的制动控制附Matlab代码
  • 【优化调度】电动车协调与非协调充放电的比较分析附Matlab代码
  • Linux运维实战:巧用mv命令管理多版本Go环境,避免采坑
  • Context Engineering 3.0:企业级上下文工程,非常详细收藏我这一篇就够了
  • 《Foundation 开关》
  • XQuery 函数
  • AI专著写作攻略:选对工具,从构思到成书一步到位
  • IT数学基础番外1--手算梯度下降(TODO)
  • AI专著撰写神器来袭!快速、精准,轻松打造专业学术巨著
  • 从ResNet到mHC:DeepSeek重构残差连接,额外开销仅6.7%,附复现代码 - AI
  • Java、Python、HTML 前端后端如何配合?零基础也能看懂的毕设组合方案
  • AI教材编写秘籍揭秘!低查重的AI教材生成工具,让写作效率飙升