Orz CDQ
传送门
设$f_i$为第$i$天能获得的最大钱数,$F_i$为第$i$天持有的最大的$B$券数目,则
$$F_i=\frac{f_i}{A_i\times Rate_i+B_i}$$
$$f_i=max\lbrace f_{i-1},A_i\cdot Rate_j \cdot F_j+B_i\cdot F_j\rbrace (1\leq j<i)$$
($f_0$即为初始钱数)
若决策$j$优于决策$k(1\leq j,k<i-1)$,则
$$A_i\cdot Rate_j \cdot F_j+B_i\cdot F_j>A_i\cdot Rate_k \cdot F_k+B_i\cdot F_k$$
$$A_i(F_j\cdot Rate_j-F_k\cdot Rate_k)>-B_i(F_j-F_k)$$
$$\frac{F_j-F_k}{F_j\cdot Rate_j-F_k\cdot Rate_k}>-\frac{A_i}{B_i}$$
设$G_i=F_i\cdot Rate_i$
$$\frac{F_j-F_k}{G_j-G_k}>-\frac{A_i}{B_i}$$
左边那一坨就是$(G_j,F_j),(G_k,F_k)$两点连线的斜率
$$f_i=max(f_{i-1},max\lbrace A_i\cdot G_j+B_i\cdot F_j\rbrace) (1\leq j<i)$$
实际上就是求所有$j\in [1,i)$中的点$(G_j,F_j)$代入直线$A_i\cdot x+B_i\cdot y+d=0$后最小的$d$(最大的$-d$)
也就是说拿这条直线一点点往下移,从上往下碰到的第一个点$(G_j,F_j)$使得截距最大的就是答案,而这个点显然是在凸包上的
$p14y 2333Splay的写法有空了再慢慢写(UPD:已弃坑),先贴CDQ分治的…
具体搞法大概是这个姿势:
- 首先把所有询问按$-\frac{A_i}{B_i}$递减排序(斜率由近似水平逐渐顺时针变到近似垂直,这样好切凸包)
- 定义一个$Solve(l,r)$函数,然后分成$Solve(l,mid)$与$Solve(mid+1,r)$
- 对于$Solve(l,mid)$,继续递归处理,然后搞一个$(l,mid)$的上凸壳来更新$(mid+1,r)$的决策
- 递归$Solve(mid+1,r)$
Tips
每个$Solve$过程在更新答案后需要把区间里的询问先回复到原顺序依次处理
$Solve$结束时把$(l,r)$里的按照$F$值排序,使$F$保持递增,好更新后面的答案
1 | program bzoj_1492; |