好像是多项式最基础的算法(?,但是咕了比较久,现在学一下吧。
差值是啥
这个东西类似于 FFT 的转化过程,就是多项式点值和多项式系数的转化,简而言之就是解决下面的问题,P4781。
已知一个 n−1 次多项式的 n 个点值,f(xi)=yi,已知 k,求 f(k)mod998244353。
n≤2000
咋做
显然可以直接列方程然后高斯消元,复杂度 O(n3),非常寻宝。
考虑一个构造,令 F(x)=∑fi(x)yifi(xi),其中 fi(x) 是一个和 xi 有关的多项式,满足 fi(xi)≠0,fi(xj)=0(j≠i),这样就可以满足 F(xi)=yi 了,因为其他项全都是 0。
再考虑怎么去构造这个 fi(x)。
因为显然 xi 互不相同,所以可以构造出:
fi(x)=∏j≠i(x−xj)
最后整理一下,可以得到:
F(k)=n∑i=1yi∏j≠i(k−xj)∏j≠i(xi−xj)
直接计算,时间复杂度 O(n2)。
code
上面部分相当于一个前缀乘上一个后缀可以直接预处理,下面部分相当于每次一个阶乘乘上一些 −1,可以列出:
F(k)=n∑i=1yi∏j≠i(k−xj)(i−1)!(n−i)!(−1)n−i
时间复杂度 O(n)。
上面的做法可以查询出一个值,但是这个多项式具体是啥呢。
其实也很简单,考虑主要麻烦的是 ∏j≠i(k−xj),可以先算 ∏(k−xi) 然后再去除就好了。
做题记录
CF622F *2600
已知 n,k,求 ∑ni=1ik。
n≤109,k≤106。
比较板子的题。
考虑设 f(x)=∑xi=1ik,最后要求的就是 f(n)。
考虑 f(x) 的次数是多少,考虑差分一下,f(x)−f(x−1)=xk,这是个 k 次项式子,那么根据多项式基本知识,前缀和次数加一,所以原式是 k+1 次多项式。
所以直接差值,然后用点值连续的做就好了。
code
P5667
已知 n,m,以及 f(0),f(1)…f(n),求 f(m),f(m+1)…f(m+n)。
n≤160000,n<m≤108。
求连续点值可以做到 O(n2),寄。
发现要求的点值连续,考虑直接推式,此处为了方便先把 n 加一。
f(k)=n∑i=1yik!(k−n)!(k−i+1)(i−1)!(n−i)!(−1)n−i
这个式子和上面的本质相同。
f(k)=k!(k−n)!n∑i=1yi(k−i+1)(i−1)!(n−i)!(−1)n−i=k!(k−n)!n∑i=1yi(i−1)!(n−i)!(−1)n−i1k−i+1
直接卷积即可。
code
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话