CF802O April Fools' Problem (hard)

更好的阅读体验

题意

\(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)\)

代码 codeforces submission 143973639

posted @ 2022-02-01 10:06  gzezFISHER  阅读(29)  评论(0编辑  收藏  举报