题意
有 \(n\) 道题,第 \(i\) 天可以花费 \(a_i\) 准备一道题,花费 \(b_i\) 打印一道题,每天最多准备一道题,打印一道题,准备的题可以留到以后打印,求打印 \(k\) 道题的最小花费.
\(1\le k\le n\le 5\times10^5\)
题解
显然可以费用流解决,建图如下.
考虑优化费用流
引理
初始不含负圈的图在费用流的增广过程中不会出现负圈
根据引理得,每次增广的增广路都是一条形如 \(S\rightarrow X\rightarrow Y\rightarrow T'\rightarrow T\) 的路径,一共增广 \(k\) 次.
设 \(f_i\) 表示在残流网络上 \(i+1\) 点向 \(i\) 的流量,则一条增广路合法当且仅当 \(S\rightarrow X,Y\rightarrow T'\) 这两条边有流量且满足下列两个条件之一:
- \(X\le Y\)
- \(X>Y\land \min_{Y\le i<X}f_i>0\)
我们尝试用线段树来模拟这一过程,对于每一个区间 \([l, r]\),维护 \(a\) 的最小值计为 \(ma\),\(b\) 的最小值计为 \(mb\),从 \(x\) 到 \(l\) 有流量的最小 \(a_x\) 计为 \(fa\),从 \(r+1\) 到 \(x\) 有流量的最小 \(b_x\) 计为 \(fb\),从左到右的最小费用流计为 \(f1\),从右到左的最小费用流计为 \(f2\),从 \(r+1\) 到 \(l\) 的流量计为 \(f\)
每找到一条增广路,在线段树上更新流量并把 \(a_X,b_Y\) 赋值 \(\text{Infinity}\) 以标记 \(S\rightarrow X,Y\rightarrow T'\) 这两条边没有流量
这时候我们发现这个做法是不可行的,应为我们没法对流量快速地区间修改
发现 \(f_n\) 的值总是 \(0\),我们将 \(fa\),\(fb\) 和 \(f2\) 的定义修改为在整个区间每条边的流量都减去 \(f\) 时原定义的值,这样一来区间 \([1, n]\) (也就是我们需要查询的区间) 的值是符合原定义的,二来区间修改时我们只需要更新流量,每次增广的时间复杂度可以做到 \(\Theta(\log n)\)
总时间复杂度为 \(\Theta(k\log n)\)