cdq分治与斜率优化
感触太多了,一定要写一篇blog
斜率优化真的是一个比较麻烦的东西,和数学的结合性很强,我数学又不太好
就是要看是使dp值最大还是最小,维护斜率单减或者单增
拿这一题P5785 [SDOI2012]任务安排来说,有几个要点:
1. 单纯的二分查找是有一定的局限性的(比如说跑得快),如果 c(i) 也不保证非负的话,就不能用。这时如果你又不想写李超树的话,cdq分治就派上大用场了。
2. 斜率 dp 的式子往往可变化性比较强,比如说式子可以写成这样:
fj = ti * ci + ti * cj - s * cn + s * cj
这时候可以吧(ti+s)看做斜率,cj 看做横坐标,fj 看做纵坐标
如果变形成这样:
fj -s * cj = ti * ci + ti * cj - s * cn
就可以吧 ti 看做斜率,把 cj 看做横坐标,把 fj -s * cj 看做纵坐标
是这样吗?本人写的是后一种,前一种是大多题解写的,但本人貌似写不对。。
3. cdq分治的技巧是强加单调性,一般是现将斜率排序,
分治时,按时间划分到左右两个区间(即只能用时间小的更新时间大的),然后递归处理左区间
接着用左区间构建凸 ( 凹 ) 包,用来更新右区间,因为这时右区间斜率是单增的,可以直接用单调栈
然后递归处理右区间
最后按照横坐标升序归并上传,这样这一段就可以构建凸包了
还有一些细节:
1.精度很容易被卡,请见小叔精度的一些问题
2.#define X(i) Y(i) K(i) 的时候,注意多项式要加括号!!!
比如#define Y(i) f[i]+a[i] 就是不对的,这样Y(i)-Y(j) 就变成了 f[i]+a[i]-f[j]+a[j]
应该写成 #define Y(i) (f[i]+a[i])

浙公网安备 33010602011771号