codechef PBOXES

把所有盒子按照\(S\)为第一关键字价值为第二关键字排序。
根据雪灾与外卖,我们可以这样建图:
\(s->i\)连费用为价格,流量为\(1\)的边
\(i->i-1\)连费用为\(0\),流量为\(\inf\)的边。
\(i->t\)连费用为价格的相反数,流量为\(1\)的边。
然后跑最大费用最大流。
虽然我们可以从\(s->i->t\)增广,但是我们这样子肯定是不优的。
由于费用流基本性质,增广得到的代价\(<=0\)即可跳出。
所以这样子是正确的。
然而数据范围非常大。这样子肯定是会tle的。
我们增广的路径肯定是形如\(s->i->j->t\)的。
然后增广完以后,会添加反向边。
然而我们会发现根据费用流基本性质,与源/汇点相连的边不会被退流。所以一个\(s->i\)\(i->t\)的边被流过后可以被立刻删除。
考虑过中线分治。分\(i<j\)\(i>j\)讨论。
1.\(i<j\)
我们把右边的最大值和左边的最小值取出来作差即可得到答案。
显然可以用线段树维护。然后用线段树区间加法,把\([i,j-1]\)处的边流量\(+1\)
2.\(i>j\)
这要求\([j,i-1]\)的边流量都\(>0\)
注意到当\(i\)右移或者\(j\)左移,我们肯定更不会满足条件。
所以维护\(lm,rm\)表示能被退流的前/后缀,\(lx,rx\)表示能被退流到的前/后缀的最大值。
容易发现我们修改一个节点只会影响\(\log_2n\)个节点的值,所以可以用线段树维护。
时间复杂度\(O(n\log_2n)\)

posted @ 2021-01-12 15:53  celerity1  阅读(69)  评论(0编辑  收藏  举报