拉格朗日插值

拉格朗日插值

给定 \(n\) 个点 \((x_i,y_i)\),构造一个函数 \(f(x)\) 使得对于任意的 \(i\in [1,n]\)\(f(x_i)=y_i\) 恒成立。

考虑构造 \(n\) 个函数 \(f_i(x)\),使得 \(f_i(x_j)=[i=j]\)。不难发现可以令 \(f_i(x)=\prod_{j\neq i}\frac{x-x_j}{x_i-x_j}\),则最终不难构造出 \(f(x)=\sum_{i=1}^ny_i\times f_i(x)\)

当给定的 \(x_i\) 连续的时候,不妨假设此时 \(x_1=1\)。此时新的式子为 \(f(x)=\sum_{i=1}^n y_i\times \prod_{i\neq j}\frac{x-j}{i-j}\)。此时设 \(pre_i=\prod_{j=1}^i(x-j)\)\(suf_i=\prod_{j=i}^n(x-j)\),则可以化简得到:

\[f(x)=\sum_{i=1}^n y_i\times (-1)^{n-i}\times \frac{pre_{i-1}\times suf_{i+1}}{(i-1)!\times (n-i)!} \]

可以 \(O(n)\) 计算一个点的点值。对于 \(x_1\ne 1\) 的情况,只需要对 \(pre\)\(suf\) 的定义略加修改即可。

插值求多项式系数

多项式形如 \(f(x)=\sum_{i=1}^n y_i\times \prod_{j\ne i}\frac{x-x_j}{x_i-x_j}\)。考虑对于每一个 \(i\) 分别计算,最后求和。提出常数倍 \(a_i=\frac{y_i}{\prod_{j\ne i}x_i-x_j}\),设 \(g(x)=\prod_{i=1}^n(x-x_i)\),则有 \(f(x)=\sum_{i=1}^na_i\times \frac{g(x)}{x-x_i}\)\(g(x)\) 的系数可以 \(O(n^2)\) 暴力乘每一项求出;设 \(h(x)=\frac{g(x)}{x-x_i}\),每次枚举 \(i\) 计算答案然后相加,设当前 \(x_i\)\(c\),我们有 \([x^n]g(x)=[x^{n-1}]h(x)-c[x^n]h(x)\),于是可以递推求每一个 \([x^n]h(x)\)\(0\) 次项系数显然是 \(\frac{[x^0]g(x)}{-x_i}\)。因此求 \(f(x)\) 每一项系数的总复杂度为 \(O(n^2\log V)\)。一般插值时可以预处理 \(c\) 的逆元来去掉一个 \(\log\)

例题

P4463 [集训队互测 2012] calc

题意:我们称一个序列合法,当且仅当其每个位置的值互不相同且均在 \([1,k]\) 内。设一个合法序列的权值为 \(\prod a_i\),求所有长为 \(n\) 的合法序列的权值和。\(n\leq 500,k\leq 10^9\)

首先,序列打乱后权值不变,因此考虑只统计单调序列的答案,最后乘一个 \(n!\)

\(f_{i,j}\) 表示考虑前 \(i\) 个位置的单增序列,最后一个元素不大于 \(j\) 的权值和,显然有 \(f_{i,j}=f_{i-1,j-1}\times j+f_{i,j-1}\)。复杂度 \(O(nk)\)

考虑归纳说明两个事实:

  • 首先当 \(n=1\) 时,\(f(n,x)=x\) 是关于 \(x\) 的多项式函数。若 \(n=m\) 时满足条件,则 \(f(n,x)\times (x+1)\) 显然也是关于 \(x\) 的多项式函数。因此 \(f(m+1,x)\) 的差分是关于 \(x\) 的多项式函数。
  • \(x=n\) 时,\(f_{n,x}=x!\) 是关于 \(x\) 的多项式函数,且差分也是。故对于任意 \(n\leq x\) 可归纳得出其为关于 \(x\) 的多项式函数。

考虑设 \(g_n\) 表示 \(f_n\) 的次数。由于多项式函数做差分(求导)会导致次数降 \(1\),故根据 \(f_{n,x}-f_{n,x-1}=f_{n-1,x-1}\times x\) 可推知 \(g_{n}-1=g_{n-1}+1\),又 \(g_{1}=2\),故有 \(g_n=2n\),暴力 dp 找 \(2n+1\) 个点进行插值即可。复杂度 \(O(n^2)\)

[ABC208F] Cumulative Sum

题意:给定非负整数 \(n\)\(m\) 和正整数 \(k\)。求函数

\[ \displaystyle\ f(n,\ m)\ = \begin{cases}\ 0\ &\ (n\ =\ 0)\ \\ n^K\ &\ (n\ \gt\ 0,\ m\ =\ 0)\ \\ f(n-1,\ m)\ +\ f(n,\ m-1)\ \ &\ (n\ \gt\ 0,\ m\ \gt\ 0)\ \end{cases} \]

\(\left(10^9+7\right)\) 取模后的值。

网格图优化 dp 的形式比较显然。注意到 \((n,0)\) 只能转移到 \((n,1)\),所以实际上是从 \((i,1)\) 走到 \((n,m)\) 的路径计数。不难写出式子 \(f(n,m)=\sum_{i=1}^ni^k\binom{n+m-1-i}{m-1}\)。注意到 \(i^k\)\(i\)\(k\) 次多项式,把组合数拆开,分子的 \((n+m-1-i)\)\(i\)\(n+m-1-i\) 次多项式;分母的 \((m-1)!\) 是常数,\((n-i)!\)\(i\)\((n-i)\) 次多项式,故整体是 \(i\)\(m+k-1\) 次多项式。求前缀和(是差分的逆运算)后次数增加 \(1\),故 \(f(n,m)\) 是关于 \(n\)\(m+k\) 次多项式。利用给出的式子暴力递推求出 \(f(1,m)\sim f(m+k+1,m)\),然后插值即可。复杂度 \(O(mk)\)

CF995F Cowmpany Cowmpensation

题意:给定一棵 \(n\) 个点的树,求有多少种给点赋 \([1,d]\) 内的权值的方式,使得任意儿子节点的权值不超过父亲。\(n\leq 3000\)\(d=10^9\)

集训队互测那个题的树上版本。设 \(f_{i,j}\) 表示点 \(i\) 填的数不超过 \(j\) 的方案数,我们有 \(f_{i,j}=f_{i,j-1}+\prod f_{v,j}\)

下面证明 \(f_{i,j}\) 是关于 \(j\)\(sz_i\) 次多项式。其在叶子处显然成立,若 \(i\) 点的所有儿子该结论均成立,考虑转换为差分形式后,\(f_{i,j}-f_{i,j-1}=\prod f_{v,j}\),差分为 \(sz_i-1\) 次式,则 \(f_{i,j}\) 显然为 \(sz_i\) 次式,递推成立。故暴力求出前 \(n+1\) 个 dp 值,插值即可求出答案。这里的瓶颈在 dp,复杂度 \(O(n^2)\)

P8290 [省选联考 2022] 填树

题意:给定一棵 \(n\) 个点的树,第 \(i\) 个点的值域限制区间为 \([l_i,r_i]\),你可以任选一条链,给链上的所有点赋值域限制区间内的值。问最后有多少种不同的树,使得非零权值的极差不超过 \(K\), 并求出所有合法树的权值和。\(n\leq 200\)\(1\leq l_i,r_i,k\leq 10^9\)

首先考虑朴素的 dp。我们不希望同时在 dp 状态中记录最大值和最小值,考虑只枚举最小值 \(L\),则值域被限制在 \([L,L+k]\),此时可能会算重,因此我们再减去 \([L+1,L+k]\) 的答案即可。对于一个固定的 \(L\)\(k\),设 \(f_{i}\) 表示 \(i\) 子树内到 \(i\) 的合法链的数量;\(g_i\) 表示 \(i\) 子树内到 \(i\) 的合法链权值和。预处理 \(num_i\) 表示 \(i\) 点可以填的数的个数;\(sum_i\) 表示 \(i\) 点可以填的数的和。同时维护 \(ans_1,ans_2\) 分别表示两个问题的答案。考虑逐子树合并求答案,设当前点为 \(i\)、需要合并的那个子树为 \(j\),初始时有 \(f_i=num_i,g_i=sum_i\),我们有如下式子:

\[num_i=\max(0,\min(L+k,r_i)-\max(L,l_i)+1)\\ sum_i=\frac{(\min(L+k,r_i)+\max(L,l_i))\times num_i}{2}\\ f_i\gets num_i\times f_j\\ g_i\gets num_i\times g_j+sum_i\times f_j\\ ans_1\gets f_i\times f_j\\ ans_2\gets f_i\times g_j+f_j\times g_i \]

于是得到一个 \(O(nV)\) 的做法。考虑优化。

不妨把 \(num_i\)\(sum_i\) 式子中的 \(\min,\max\) 通过分类讨论拆掉,首先显然要按照 \(r_i-k\)\(l_i\) 分段:

  • \(L\geq l_i\) 时:
    • \(L+k\geq r_i\),则 \(num_i=\max(0,r_i-L+1)\),还需要按照 \(r_i+1\) 分段;
    • 否则 \(num_i=L+k-L+1\)
  • \(L<l_i\) 时:
    • \(L+k\geq r_i\),则 \(num_i=r_i-l_i+1\)
    • 否则 \(num_i=\max(0,L+k-l_i+1)\),还需要按照 \(l_i-k-1\) 分段。

不难发现我们可以分出 \(O(n)\) 段。

此后,在每一段内,\(num_i\) 是关于 \(L\) 的一次式,\(sum_i\) 是关于 \(L\) 的二次式,在叶子处 \(f_i=num_i,g_i=sum_i\)。根据上面的式子,我们发现 \(f_i\) 的次数是 \(f_j\) 的最大次数 \(+1\)\(g_i\) 的次数是 \(f_j\) 的最大次数 \(+2\)\(g_j\) 的最大次数 \(+1\),也就是说,\(f_i\) 的次数是子树内到 \(i\) 的最大链长;\(g_i\) 的次数是子树内到 \(i\) 的最大链长 \(+1\)。同理可得,\(ans_1\) 的最大次数为 \(n\)\(ans_2\) 的最大次数为 \(n+1\)。由于我们需要对所有 \(L\) 的答案求和,故累加起来得到 \(ans\) 的次数不超过 \(n+2\)

于是对于每一段,我们需要求出 \(n+3\) 个前缀和的点值,需要跑 \(n+3\) 次上述的 dp,然后做 \(x\) 连续的插值。总复杂度瓶颈在 \(O(n^2)\) 次 dp 上,为 \(O(n^3)\)

P5469 [NOI2019] 机器人

题意:场地上有 \(n\) 个柱子,有两种波特,第一种波特从起点开始一直往左,直到下一个柱子比起点柱子高(或没有柱子了)就停下;第二种波特从起点开始一直往右,直到下一个柱子不低于起点柱子(或没有柱子了)就停下。现在每个柱子的高度限制为 \([A_i,B_i]\),问有多少种设定高度的方式,使得无论把两个波特同时放在哪一个柱子上,它们走过的柱子数目的差的绝对值都不超过 \(2\)\(n\leq 300\)\(1\leq A,B\leq 10^9\)

对于 f(x) 会从 f(x-k) 转移来的情况,若需要分段做拉格朗日插值,似乎需要保证 k 不超过 1。原因是 k 更大后,一段的段首会从上一段函数不同的位置转移过来,导致段首的函数与后面的不同,进而导致每一个位置的函数都不同。k=1 合法是因为交界处的点同时满足前后两个函数。

考虑找到 \(n\) 个柱子中最靠右的最高的那一个,设其位置为 \(p\)。则以 \(p\) 作为起点时,往左往右都会走到底。因此,\(p\) 一定在区间中点偏移不超过 \(1\) 的地方,长为奇数的区间有 \(3\) 个合法位置;长为偶数的区间有 \(2\) 个合法位置。此后,从其他位置出发的波特都不可能越过 \(p\)。因此考虑区间 dp:\(f_{i,j,k}\) 表示区间 \((i,j)\) 的最大值不超过 \(k\) 的方案数(滚一个前缀和便于转移),转移是 \(f_{i,j,k}=\sum f_{i,p-1,k}\times f_{p+1,j,k-1}+f_{i,j,k-1}\)。初始值是 \(f_{i+1,i,x}=1\)\(f_{i,i,x}=\max(0,\min(x,B_i)-A_i+1)\)

首先由于 \(p\) 的可行位置很少,猜测会用到的区间不多,打表发现只有 \(m=2000\) 多个。考虑到 \(k\) 过大,我们需要插值计算。为了去掉式子里的 \(\min\)\(\max\),我们显然要分段,段之间交界的 \(O(n)\) 个位置是 \(B_i\)\(A_i-1\)。此处需要注意:由于转移时涉及到 \(k-1\) 的部分,我们需要 \(k-1\) 也符合当前段的函数,才可以利用 \(k\) 来插值。注意到段的交界处同时满足两侧的函数,因此可以将每一段的起点设为 \(A_i\)\(B_i+1\),这样直接选取段头的值来插值,就是正确的。

归纳可知,同一段中 \(f_{i,j,k}\)\(i,j\) 固定的前提下,是一个关于 \(k\)\((j-i+1)\) 次式。因此每一段对前 \(n+1\) 个值暴力 dp 求解,然后插值即可。每一段需要对段尾巴处的值做 \(O(m)\) 次插值,预处理阶乘逆元和前后缀乘积可以做到 \(O(mn^2)\)。通过一些优化减少取模次数后(例如预处理、做 \(8\) 次乘法求和后再取模等),可以通过。

CF1874E Jellyfish and Hack

题意:我们设对一个长度为 \(n\) 的排列 \(p\) 做错误的快速排序,每次把小于 \(p_1\) 的按顺序放进 \(L\),大于的放进 \(R\),则设其复杂度函数为 \(f(p)=n+f(L)+f(R)\),空序列为 \(0\)。问有多少种排列的 \(f\) 大于等于 \(lim\)\(n\leq 200\)

拉插优化卷积形式 dp,和 24 年省选重塑时光的最后一步优化是同一个 trick。

首先有一个简单的 dp:设 \(f_{i,j}\) 表示长度为 \(i\) 的排列,函数值为 \(j\) 的方案数。枚举排列第一项转移,有 \(f_{i,j}=\sum_{p=1}^i\binom{i-1}{p-1}\sum_{k=0}^{j-i}f_{p-1,k}f_{n-p,j-i-k}\)。此时可以做到 \(O(n^6)\)

考虑优化。注意到后面是一个卷积形式,我们可以用 OGF 做,不难写成多项式形式:\(F_i=\sum_{p=1}^i\binom{i-1}{p-1}F_{p-1}F_{n-p}x^{i}\)。我们最后希望求得 \(F_n\) 的各项系数。注意到 \(F\) 是一个至多 \(\frac{n(n+1)}{2}\) 次的多项式。于是我们代入 \(x=1\sim \frac{n(n+1)}{2}+1\) 这些点值递推出 \(F_n\) 的点值即可,单个点值的递推复杂度是 \(O(n^2)\),总复杂度 \(O(n^4)\)。递推起点是 \(F(0)=1\)。最后利用这些点值把 \(F_n\) 的各项系数用上文方法插出来即可,复杂度也是 \(O(n^4)\)

posted @ 2025-03-02 17:12  烟山嘉鸿  阅读(59)  评论(0)    收藏  举报