AtCoder Regular Contest 125 比赛记录(vp)

得分情况

赛时:B

赛后:ABCD

题解

A,B 略

C

首先我们可以很容易的玩出来,如果 \(A_1,A_2...A_k\) 是一个 LIS,那 \(A_1\) 一定在最前面。因为如果有一个比 \(A_1\) 小的在前面,LIS就会变长;而 \(\ge A_1\) 的里面,经过手玩,我们似乎能构造出 \(A_1\) 在最前面的解。

我们考虑严谨的描述这个事情。手玩+想象发现,我们把 \(A_1\) 排在前面之后,要把剩下的数排过来,那应该尽量选小的。如果 \(A_1=1\),发现好像直接放 \(A_2\) 就是最优的,否则(可以手玩发现)我们可以再放一个 \(1\)\(A_1\) 的后面,然后考虑后面怎么放。

我们发现这个结构和原问题好像有点像。仔细一想,每次的决策只和剩下哪些数,当前还剩哪些 \(A\),这些东西的相对位置关系有关。也就是说,我们把 \([1...n]\) 整体平移一个 \(x\),变成 \([x+1...x+n]\),问题的答案并不改变。

我们选完了 \(A_1\) 如何放之后,发现 “1” 这个数一定被放了。后面的数一定都在 \([2,n]\) 范围里。我们给它整体 \(-1\),然后就和原问题一模一样了。

所以我们可以递归解决。设当前的LIS是 \(A\),剩下的数是 \(B\),都是排好序的。如果 \(A_1<B_1\),说明 \(A_1\) 是最小的,直接放一个 \(A_1\),搞剩下的。否则,放完 \(A_1\) 之后还可以放一个 \(B_1\),然后再放剩下的。

放到最后一个 \(A\),相当于LIS必须为 \(1\)。此时必须把 \(A,B\) 放一块,逆序排序之后排起来。很明显,之后一个完全逆序的数列能满足“LIS=1”的限制。

并不需要真的写个递归出来,我们用两个序列再加一个指针模拟一下就行了。

D

我赛场上在想如何在子序列自动机上搞一个fail

脑子一想,LIS不唯一当且仅当它可以“换”。怎么可以被换掉呢?

设子序列是 \(p_1,p_2...p_k\)。对于子序列上相邻的两个位置 \(p_i,p_{i+1}\),如果 \([p_i+1,p_{i+1}-1]\) 之间存在着某个数,和两边的任何一个相同,就可以把它换掉。此时的子序列显然不唯一。

反过来这个子序列就唯一了吗?我们发现还有两边换的情况要考虑。这好搞,我们设子序列是 \(0,p_1,p_2...p_k,n+1\),然后就可以解决这个问题。

接下来就好整了。我们相当于要数有多少种选择 \(p\) 的方案,使得任意两个位置中间夹的数和两边都不一样。

可以dp。设 \(f(i)\) 表示选到 \(i\) 位置,选出来的子序列在前缀 \(i\) 个里面唯一的方案。

枚举 \(j\)。它要满足,\([j+1,i-1]\) 区间里面的数和 \(a_i,a_j\) 都不同,才可以转移,此时 \(f(j)\) 加到 \(f(i)\)。边界条件 \(f(0)=1\)

然后搞一个pre,nex,再主席树,就可以做了!(迫真)

考虑一个好搞的做法。条件相当于,\(j>pre_i,nex_j>i\)

\(j>pre_i\),搞一个区间查询 \([pre_i+1,i-1]\) 就行了。问题是如何处理 \(nex_j>i\)

我们发现,在 \([1,i]\) 前缀中,对于每一种值,只有最后一次出现的位置是有用的。原因很简单,如果不是第一次出现,那它的 \(nex\) 肯定 \(\le i\)。我们令最后一次出现的位置有 \(f\) 值,其它位置都是 \(0\),求个区间和就行了。

如何维护 “最后一次”?考虑新加了一个 \(i\),只有 \(pre_i\) 这个位置会变成 “不是最后一次”,在这里做一个单点修改就行了。于是,单点修改,区间求和,树状数组就可以做,比主席树简单多了。

比赛实况

又没睡好,我先比赛了 1h 8min,然后睡到了倒数 10min 再起来搞题。

我先看出来了 \(A\) 的做法,然后实现挂了,因为没有加哨兵,导致它碰到 \(0\) 位置的时候出了一些问题。死活没调出来,因为挺不好调出来的。我起床后的10min都在搞,我眼看着我WA的点数越来越少,但死活没过。

我发现 \(A\) 没调出来,比较冷静,没有太多执念,就去做 \(B\) 了。发现 \(B\) 好像挺好做。果然我还是数学比较强啊。

然后就去做 \(C\)。一看,啥玩意啊,根本不会。就去随便胡了几个东西,手玩玩。好久没做这种贪心题了,手玩了好久也只看出来 \(A_1\) 排最前面这个结论。我甚至连递归结构都没发现 (其实发现递归结构这题就没了吧)

然后就去看 \(D\)。一看,啥玩意啊。

然后就去看 \(E\)。一看,啥玩意啊。

然后就滚回去看 \(D\)。我搞出来 “换子序列” 那一步。

然后就很明显是一个子序列的dp了吧喂!再想想啊草

我没去想,因为我精力不够用了。我的视线逐渐模糊,我用最后一丝力量把自己挪到了床上,然后呼呼睡大觉。原本还准备泡杯咖啡再打,我妈不让我整,就没去泡。

在床上,我睡的跟头猪一样。但我后来醒的很早,我脑子里还在想我要回去写题。然后这股劲推动着我醒来,我一看居然还有时间。原本以为我醒来就结束了(上一次就是醒来就结束了),看来这次醒的早些。

还剩下10min。我很明显想不出C,D了,就去调A,然后就是死活不对。

赛后我去下数据,对着数据搞,才勉强草过去了。

总结

  • 平常学了那么多东西赛场上要会用啊
  • 不要见到贪心题,策略题就炸了心态,多做点就好了
  • 多休息,保证赛场上精力充沛
posted @ 2021-08-26 19:59  Flandre-Zhu  阅读(76)  评论(0编辑  收藏  举报