Loading [MathJax]/jax/output/HTML-CSS/jax.js

[LibreOJ 2249][NOI2014]购票

在紧张刺激的等待之后终于肝掉了这道题……

本题的DP方程长成这样(其中av的某个满足距离限制的祖先,dvv到根的路径长):

fv=min(fa+pv(dvda)+qv)

化简之后发现:

fv=qv+pvdv+min(fapvda)

利用min中那一块很容易发现是截距式……但是问题在于,我们的转移来源是树上的连续一段祖先,怎样维护他们的凸包?

答案很狂暴啊……用树链剖分套上向量集那题的线段树套凸包,然后完了……

(注意一点细节:本题因为数据范围过大,故可能存在两个向量叉乘爆long long,所以在求凸包时如果直接用叉积判断是否需要删点会炸掉,建议用斜率判断)

代码:

[LibreOJ 2353][NOI2007]货币兑换

emmm做了一下这道神题……(我可能是少有的用动态凸包苟的?

首先DP方程长这样:

fi=max(fi1,fjAiRj+BiAjRj+Bj)

然后这个方程炒鸡复杂……首先fi1不要管了,然后设ai=fiAiRi+Bi。在xjb推了一番之后我们终于得到了截距式……

ajRjAiBi+fiBi=aj

但是这玩意太毒瘤了……斜率不可能单调的,这还好,在凸壳上二分/三分一下即可。但问题在于,横坐标也不单调……

这个时候就需要动态维护凸包了(其实是我不会CDQ),我直接把我向量集那题的二进制分组线段树搬了过来……(逃

代码:

[LibreOJ 2197][SDOI2014]向量集

xjb写了写……我评测时候心脏跳得贼快(逃

考虑如果知道了那一段区间的凸包那么怎么做。首先如果向量是往上指的话,一定在上凸壳上找点比较好,反之则在下凸壳上找点比较好(放到坐标系里脑补一下?)。然后我们观察一点,在上凸壳上的最优解往两边的点会越来越劣,所以这玩意是个上凸函数,可以三分答案(我才学的整数三分啊)。

但区间凸包求起来复杂度很爆炸啊……考虑用线段树搞?观察到一点,我们区间查询所使用的线段树节点一定是只包含了已经加进来的点。所以说,一个线段树节点的凸包需要被求的情况只有一种,那就是这个节点完全已加入点被覆盖了。那每次修改之后看是否一个节点完全被已加入点覆盖,如果被完全覆盖的话才去求它的凸包。

这样一来,线段树上每个节点之多会被求一次凸包。线段树有logn层,每一层所有节点的大小加起来是n,所以求凸包耗费的总复杂度是nlog2n级别的。

其实这就是用线段树模拟二进制分组?

代码:

[SWERC2015]Saint John Festival

第一次做像点样子的计算几何吧……

很显然要包含在某个三角形里,就要被包含在大点的凸包里。所以求出大点组成的凸包,然后对于所有小点判断它是否在那个凸包里即可。

代码: