拉格朗日插值优化值域 dp

前言

  • 主要是我对省选 2022 D1T2 一直耿耿于怀,所以就有了这一篇文章

  • 感觉这一类题目似乎都挺套路的

  • 学习不久,肯定有很多错误,望轻喷

前置知识

  • 拉格朗日插值:\(f(k)=\sum_{i=0}^n y_i\prod_{j\neq i}\frac{k-x_j}{x_i-x_j}\) ,复杂度为 \(O(n^2)\)

  • 一般的我们会用 \(1-n\) 这样的点值来做插值,原式就可以转变成 \(\sum_{i=1}^n y_i\prod_{j\neq i}\frac{k-j}{i-j}\),预处理出阶乘,复杂度就可以做到 \(O(n)\)

  • 多项式做前缀和指数+1 ,多项式相乘指数相加,多项式相加指数取最大......

问题引入

LG P3643 [APIO2016]划艇

  • 首先设计 dp

  • \(f[i][j]\) 表示前 \(i\) 个学校的最大值为 \(j\) 的方案数,\(j=0\) 表示一个都没选 ,转移式:

    • \(a_i\leq j\leq b_i,f[i][j]=\sum_{0\leq k\leq j} f[i-1][k]\)
    • 否则,\(f[i][j]=f[i-1][j]\)
  • 可以发现 \(f[i](x)\) 是一个分段函数,拉格朗日插值可以为完整不分段的多项式插值

  • 因此我们考虑将值域 \([1,10^9+1)\) 分成若干段 左闭右开 的区间,使得每一段区间都是可插值的

  • 那么 \(a_i,b_i+1\) 就是断点,将所有的这些点放在一起离散化,对于 \([pos_x,pos_{x+1})\) 每次求出 \(n+1\) 个点值即可,一共只有 \(O(n)\) 个这样的区间

  • \(f[0](x)\) 是一个常数多项式,每次转移最多是做了以一个前缀和,指数加一,所以 \(f[n](x)\) 的次数必然最大为 \(n\) ,插 \(n+1\) 个点值即可

  • 因此就是对于每一个区间维护前 \((n+1)\) 个点值,注意到这里最终插值实际上插的是一个范围,因为我们要维护区间和,所以插出来的值要是整个区间的和,所以我们维护前 \((n+1)\) 个点值的时候要维护真正的 \(f\) 的值的相对于区间的前缀和,具体可以看看代码理解

  • 参考代码

  • 一开始还 T 成了 90 ,还以为被卡常了,后来发现没开 O2

LG P5469 [NOI2019] 机器人

  • 首先设计 dp

  • 首先需要观察到对于最右边的最大值,左边和右边其实是两个独立的新的子问题

  • 那么考虑根据这个性质建立 dp 方程

  • \(f[l][r][j]\) 表示在范围内最大值 \(\leq j\) 的方案数

  • 那么每次枚举一个可以成为最大值的位置,然后枚举最大值,递归求解

  • 因为对于一个区间只有 \(1,2\) 个满足条件的位置,所以实际上的状态很少,写到这里就拿到了前 50 分

  • 我们将每个可能涉及的范围用一个数字来表示这个状态,设 \(f[now][j]\)

  • 设状态数为 \(N\) ,复杂度就是 \(O(NV)\)

  • 参考代码

  • 可以发现这里的复杂度瓶颈在值域

  • 对于 \(l=r\) 的时候,可以发现 \(f[now](x)\) 其实是个一次函数

  • 考虑每次合并,可以发现长度为 \(len\) 的区间,\(f[now](x)\) 实际上是一个 \(len\) 次多项式

  • 所以次数不会大于 \(n\) ,那么我们考虑像上一题一样用拉插来做

  • 仍然先将区间分成一个个左闭右开的区间,对于每个区间做一次 \(dp\)

  • 首先对于每个状态求出前 \(n+1\) 个插值,然后再对于每个状态做拉插,用 \(f[now][0]\) 来存前缀和即可

  • 参考代码

  • T 成 95 了,不想卡常所以所以直接特判过去了

LG P8290 [省选联考 2022] 填树

前言

  • 我是傻逼

正题

  • 首先考虑第一问

  • 考虑先确定一个最小值 \(l\) ,那么最大值的范围就是 \([l,l+K]\) ,设 \(p(l,r)\) 表示范围在 \([l,r]\) 的路径的个数

  • 那么答案实际上就是 \(\sum p(l,l+K)-p(l+1,l+K)\)

  • \(Q(l)=p(l,l+K)-p(l+1,l+K)\),那么答案就是 \(\sum Q(l)\)

  • \(p(l,r)\) 用树形 dp 可以 \(O(n)\) 解决

  • 仍然考虑按照值域分成一段段左闭右开的区间,这样每一段树形 dp 的时候都是完整的函数,可以进行拉插

  • 最后大致的分析一下多项式的指数,可以发现 \(p(l,r)\) 的指数最多就是 \(n+1\)

  • 权值也是一样的做法,不过因为乘了一个等比数列,所以指数就是 \(n+2\)

P4463 [集训队互测 2012] calc

  • 感觉这个题最多紫啊

  • \(f_{i,j}\) 表示前 \(i\) 个数,值域为 \([1,j]\) 的答案

  • \(f_{i,j}=f_{i,j-1}+jf_{i-1,j}\)

  • 发现这个式子有一维是值域,极大无比,感觉这种情况要么考虑矩乘要么就是拉插吧

  • 显然是拉插啦,考虑多项式的指数

  • 可以发现 \(f_{i,j}=2i!+if_{i-1,i}+(i+1)f_{i-1,i+1}+...\)

  • 可以发现后面的多项式整体右移了一位又做了前缀和,所以指数 +2

  • 所以对于 \(f(n)\) 的指数是 \(2n\) ,求出 \(2n+1\) 个点值然后直接插值就可以了

总结

  • 大概解决一类 dp ,有一维是值域且非常大,\(n\) 很小,复杂度猜测为 \(O(n^3)\) 左右,具有选择值域中的一个数这样的特征

  • 首先写出 dp 的式子

  • 然后考虑优化值域这一部分

  • 一般的将区间分成一段段左闭右开的区间得到完整的函数,然后分析指数,考虑拉插

posted @ 2022-06-04 10:05  Kzos_017  阅读(301)  评论(0编辑  收藏  举报