24pht春3

pht春3

A

显然 f [ i ] [ j ] f[i][j] f[i][j] 表示前 i + j i+j i+j 个,有 i i i 个用 a a a j j j 个选 b b b 的方案数。然后显然。


不是,好像假了, k + s ≠ n k+s\neq n k+s=n

直接按 a a a 排序,那样子只要不选 b b b 的肯定选 a a a


除了dp,也可以费用流。

源点连两个虚点,分别跑 X , Y X,Y X,Y 流量。然后连到每个点流量1费用 a i , b i a_i,b_i ai,bi 即可。

bonus1

首先肯定两维排序。

假设全部选 a a a,然后把一些换成 b b b。那直接作差排序即可。


a i − b i a_i-b_i aibi 排序。

必然存在一个地方,前面全部选编程,后面全部选体育。

但是中间会有一些空洞。

考虑枚举前缀(分割线),前缀里选编程的肯定是选 a i a_i ai 最大的,后缀中选 b i b_i bi 最大的。

i i i 个的topk的sum是好求的。

然后就完成了。

bonus2

三项技能。后面会讲。

B

如果还有分割次数显然选最大块的分割。

但是对于一个块,如果最后分了两次,显然不是对半分。

我觉得直接二分最大块长度应该就行了。


假设只切一个,就选最大的。

但直接增量来做是不对的。

最终局面:选出若干个胡萝卜,这些胡萝卜是一步到位切成的。

问题是每个胡萝卜要切多少份?

想象中先把切开的合起来,再重新切,也就是有一个反悔的过程。

也就是把增量的过程变成切 k k k 刀变成切 k + 1 k+1 k+1 刀的情况。

bonus

我觉得我的做法没问题。


从D回来,显然满足是上凸的,因为收益越来越小,二分斜率。

当然,也可以二分最后一次的收益。

C

相当于每个数可以加 k k k,然后求差分序列大于0的数之和(初始时0)

如果设计 f [ i ] [ j ] f[i][j] f[i][j] 表示 a i = a i + k × j a_i=a_i+k\times j ai=ai+k×j,这样子显然是没问题的。

这是 n 2 n^2 n2,第二维能不a,能搞一下呢?


首先转化和我的一样。

对于上面那个 f f f,显然 j j j 只会转移到 j + 1 , j , j − 1 j+1,j,j-1 j+1,j,j1 ,而且如果比他小只会+1,比他大只会-1。

考虑最终答案肯定是 min ⁡ f [ n ] [ 0 … n ] \min f[n][0\dots n] minf[n][0n]。但最小值一定是 f [ n ] [ 0 ] f[n][0] f[n][0],因为最后一个显然取最小是没问题的。

所以前 i i i 个的最优在 f [ i ] [ 0 ] f[i][0] f[i][0] 处取得,有 d p i = f i , 0 dp_i=f_{i,0} dpi=fi,0,但这样没法做转移。

比如 a i < a i − 1 a_i<a_{i-1} ai<ai1,从 j − 1 j-1 j1 的转移本质是当前额外多加个 k k k,相当于把代价变成了 k − d i k-d_i kdi。我们把 k − d i k-d_i kdi 仍到一个堆里,相当于可以在某个地方额外往上加一层。

好,现在考虑会 a i > a i − 1 a_i>a_{i-1} ai>ai1,现在本身要花费 d i d_i di 的代价,但如果你用之前的 k − d i k-d_i kdi,那么就不需要执行这个操作了。

其实就是要么按原计划,要么在之前下沉一轮。

那现在需不需要把 d i d_i di 放进去呢?

嗯,是需要的,因为未来可能是有更差的。

D

考虑二分图匹配。每个 a i a_i ai 只能向编号大等于它的 b i b_i bi 连边。

可以直接变成一条链,源点向每个点连,再向汇点连。那样子即可。


好像不是网络流,是费用流?


建图方法和我一样。跑最小费用流。

复杂度没问题。

bonus 1

模拟网络流。对所有 a , b a,b a,b 一起排序。

a a a 相当于后缀加。 b b b 在有的情况下是后缀减,没的情况直接丢到一个小根堆里。

好像堆不行?开两棵线段树似乎就行了?


假设画一个流的次数和总费用的图像,这显然是下凸的。(也就是增量越来越大)

现在要求这个图像横坐标为 k k k 的费用。

此时我们可以使用wqs二分。

假设斜率match,则截距最小。这应该是wqs二分的内容吧,我记得不太清了

因此对于给定斜率可以求出给定截距最小,这个截距怎么得呢?

d = f i − i k d=f_i-ik d=fiik。求 min ⁡ f i \min f_i minfi,反求 min ⁡ f i − i k \min f_i-ik minfiik,此时在看一下这个 i i i 是什么东西。

因此我们先二分(枚举斜率),现在可以选任意多个 a i , b i a_i,b_i ai,bi,只需要满足他们的集合大小相等,且每次选中一个 a i a_i ai 会扣除 k k k 的费用,求最小费用。(因为横坐标每-1,相当于每减一个,就会小 k k k

可以先把所有 a i − k a_i-k aik。然后现在要求 min ⁡ ( ∑ b i − a j + k ) \min (\sum b_i-a_j+k) min(biaj+k),这个变成了低买高卖股票这个经典的普及组问题。

遇到 a i a_i ai 塞入队列,遇到 b i b_i bi 先优先和 a i a_i ai 配对,然后把 − b i -b_i bi 扔回进去,因为 b i b_i bi 也是可以反悔的。同时在此记录选了多少个,然后调整斜率。


wqs发现是凸的一般有:

  1. 可以转化为费用流模型
  2. 盲猜
    1. 直接打wqs上去
    2. 随机生成数据然后 n 2 n^2 n2 一样。

bonus 2

同bonus1。


刚刚做法是wqs二分的局限。

某个东西wqs可做,现在每个都要做,则使用闵可斯基和的算法。

正常容易分治。左右返回的结果都是凸的,然后就可以合并。

但这题不容易分治。因为返回的是 n 2 n^2 n2 的东西,表示选了多少个 a a a,那边选了多少个 b b b

但ABC上上周的最后一题用的是闵可夫斯基和。


对于这题还可以用线段树来做。

把它想象成选 a i a_i ai 是左括号,选 b i b_i bi 是右。然后用线段树维护只选左,只选右,选左+右的代价。

但是第二次可能可以选右+左 ()(),但有些时候也不行。

用左+右是可行的,用右+左不一定行。

本质是括号匹配中对于这些括号是不会退流,但是配对会退流。

对于目前选右+左,只需要满足前缀和>0,就可以。

但这样子不能用线段树简单维护,因为可能出现这样子的情况,[()()()],会新增很多不连读段。

因此要多维护几个东西。

  • 区间最大r在l前的东西。

  • 区间内前缀和最小的值 v 1 v_1 v1

  • 区间内RL从大于最小值的地方返回的RL‘。

我们在某些时候可以把第一种转化为第三种。

然后每次选左右括号,然后区间±1,然后还有各种更新。

其实是利用12中的辅助信息求出3的信息。


打完后还是感觉wqs比费用流好打(如果copy板子很难说)

但考场上打wqs直接飞起

E

同样,直接对敌人强弱排序,然后连边,但此题变成费用流了。

a a a 的加入显然是有序,另一边按 − b + c -b+c b+c 排序后加入,应该就和上一题一样了。


题目钦定红点在蓝点前面,匹配有价值,和上一题一模一样。但这题不限选次数,所以其实就是wqs二分内部的判断。

F

50分显然。

正解我想想。


把负的去掉,变成一段段。

奇数位放上面,偶数位放下面,然后奇数和前后偶数相连。然后前后都连1的流量,中间边是两个点的max值。那样子肯定就符合。

因为此时是凸的可以wqs二分。


这题可以更简单。

假如 k = 1 k=1 k=1,只会选最大的。

从变大的过程中,如果出现反悔,那么肯定是相邻的两条都同时选中。

考虑现在变成另一个问题,一开始选择一个最大价值。一个不选,相当于左右都选。我们在左右连一条边。由 b + c b+c b+c 取代 a a a。代价是 x = b + c − a x=b+c-a x=b+ca,并把原先3个破坏掉。

然后可能又会连一条 x + e − d x+e-d x+ed

因此每次选了一个,直接把相邻3个全部删掉,然后在加入新的收益。

G

听说是道很厉害的贪心


首先是不是凸的?显然不是 。

按某个规则排序?

按照 b i b_i bi 2 a i 2a_i 2ai 的关系。

b i > 2 a i b_i>2a_i bi>2ai 可以拆成两个东西考虑。

b i < 2 a i b_i<2a_i bi<2ai,如果选 a a a 那么只会选一个。也就是按 b i b_i bi 排序,在后缀里面选最小 a i a_i ai

对于两类,分别选 t t t 个的答案都是易求的。


如果对于每个 k k k 都要输出呢?能不能闵可夫斯基和?

考虑函数虽然不凸,但如果分成两类,而且是直接奇偶分,那样子两个子函数都是凸的。

此时我们就可以分治。传入 [ l , r ] [l,r] [l,r],吐出一个一维的 [ i , f i ] [i,f_i] [i,fi],会分成 [ l , m i d ] , [ m i d + 1 , r ] [l,mid],[mid+1,r] [l,mid],[mid+1,r]。分别把奇偶节点取出来,都是凸的,分别做闵可夫斯基和,两个独立的都是凸的。(要分讨是奇偶偶奇和奇奇偶偶)


对于第一种做法,在 b < 2 a i b<2a_i b<2ai 时,还需分讨一下。

H

不知道为什么是交互。

从左到右做,并且每一次钦定当前元素只和前面的连接的当前最小费用。

虽然这不是最优的,但我们有当前最优结果,我们现在要允许他可以反悔。虚拟无穷红蓝点。

假设B-R连(只出现过一个B),How允许反悔呢?

假设未来有个B‘,未来的最优决策是和R连,那么这个R就可以不和原先的B连。新代价是 B − R B-R BR,反悔代价是 R − b R-b Rb

f = − R − ( R − b ) f=-R-(R-b) f=R(Rb) 塞到红色的反悔堆里面去。遇到蓝色节点就从红色点堆里取,此时是 B + f B+f B+f

所以我们并不是和上一个最近的相连,而是取出不同颜色反悔堆中取出。我们要 w = min ⁡ ( R − b , R + f ) w=\min(R-b,R+f) w=min(Rb,R+f),同时塞入 − w − R -w-R wR。其中 b b b 表示最近颜色。( R − b R-b Rb 就没必要塞到反悔堆里面了为什么我感觉需要啊?

事情还没结束。R BBBBBBBBBB,后面这些B都会连前面的R。现在有了一个R,那肯定会有一堆B和这个R连。

因此我们要在堆里面取出尽可能多的 R + w R+w R+w w w w 落在蓝色队列里面的东西。不需要丢回红色堆里。因为对于这个红色点来说只会反悔一次。

这里有几个地方值得思考:

我们每次反悔肯定会满足之前都能匹配。

我们就是要先满足当前自己的匹配。

然后去把之前对于旧有匹配不满意的对方颜色进行翻转。


丢个聊天记录:

老师,那道G题红蓝反悔匹配那题,是不是对于每个颜色操作时只需要往堆里丢一次啊?

每个颜色要先满足自己的匹配,而只需要在这个时候丢进去

然后解决掉前面其他可能对现状不满意的匹配,这步需不需要仍到对方颜色的堆里啊?

我刚刚感觉似乎不太需要,但现在感觉可能又需要。如果丢进去的话此时f就不是我们一开始推出的-2R-B了,而是只含-R

我的意思大致就是说现在到红色点,肯定只需要往红色点里面丢一次。但是帮助其他蓝色点的匹配是否需要往蓝色堆里面扔?

还有另一个问题就是你上课当时说如果这个R和B匹配是和最近B匹配而不是反悔某个B,那样子就不需要丢到红色堆里。这里不太理解,我感觉是需要丢进去的吧?

老师

需要,因为那个不满的蓝色可能将来和其他红色匹配更佳。

也是需要的。

我刚刚也交了一发代码到比赛里

I

A题的bonus2

显然我还没想到。


假设先全选 a i a_i ai,剩下的代价就是 b i − a i , c i − a i b_i-a_i,c_i-a_i biai,ciai

然后就和A的bonus1一样了。

J

从费用流角度来思考。

左边有 n n n 个点,右边有10个点。每个人连向右边一个点。然后中间连边 ( 1 , c i , j ) (1,c_{i,j}) (1,ci,j),然后向终点连 ( a j , 0 ) (a_j,0) (aj,0)

每一次每个人就是选最小边,然后流过去。

我们考虑逐个加人,每个人尝试选最小边。但如果爆了,就要返流了。

对于第 i i i 个人,可能发生 i − 1 i-1 i1 次返流。

返流相当于走最短路,而最短路每个点最多走两次,那样子返流长度不会超过20。

但复杂度还是不对,因为你不知道返流走那条路是最优的,因为会扩展到 n n n 个节点。

考虑往回增广到左边节点,我们并不关心新拓展到的节点,我们只关心从右边的节点走到右边的节点。

如果我们每次处理好了右边的Floyd矩阵,但要保证不共享左边的点。

怎么保证?考虑第一次,求出最短路为 ( 1 , i ) (1,i) (1,i),费用是 c 1 , i c_{1,i} c1,i。未来某个时刻希望1流向 j j j,相当于发生了 d [ i ] [ j ] = c 1 , i − c 1 , i d[i][j]=c_{1,i}-c_{1,i} d[i][j]=c1,ic1,i,但并不知道去 ( 1 , j ) (1,j) (1,j) 还是 ( 1 , k ) (1,k) (1,k)。对于每个 j j j,又要往Floyd矩阵上转。但现在不是矩阵了,是一个set了。把 c 1 , i − c 1 , i c_{1,i}-c_{1,i} c1,ic1,i 塞入 s e t [ i ] [ j ] set[i][j] set[i][j],那样子可以快速求出当前最短路。然后再重新塞回set里。

但这样子只能保证这一次正确,不能保证未来正确。

因此我们要重新调整set。


真无语了,这题调了半天就是set只按了其中一维排序,这时就算另一维不同set也会合并在一起。果然一段时间没打代码码力严重下降。

  • 12
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值