JOISC2020补题记

Day1

T1 建筑装饰4

不难想到暴力dp
(f[i][0/1][j])表示当前插入了(i)个数,末尾是A/B,有(j)个A中的数是否可行

暴力转移时间复杂度(O(n^2))

尝试压状态

打表发现dp值可行的j是连续段

时间复杂度变为(O(n))

code

T2 汉堡肉

据说正解是分类讨论+线段树优化建图+2sat?

写的比较流行的随机化

random_shuffle后取前四个矩形分别作为四个点的范围

然后依次加入矩形,判断与当前四个矩形哪个交集大就与哪个合并在一起

玄学可过

code

T3 扫除

神仙数据结构

先考虑没有插入的情况

注意H或者V操作只会对某一维造成影响

想到对每一维分开搞

但是H操作和V操作会有相互影响

举个例子

假设你当前有一个H操作要横着推

但是有一个覆盖范围很短但是推得距离很长的F操作竖着推走了你H操作要推的一部分灰尘

这个时候你的H操作的覆盖范围就会改变,是一个区间取max的操作

于是我们可以维护出所有H和V操作在自己一维坐标的覆盖范围

发现所有的区间要么不交要么共左端点

于是就可以两维分开处理按覆盖长度排序倒序加入取max就好了

如果要动态插入直接线段树分治解决就好了

code

Day2

T1 交互题先咕着

T2 有趣的 Joitter 交友

set启发式合并

维护一个点的出入,所在连通块的出入和点集

插入一组关系就可以在set里查一下是否会产生新关系

总添加数量是(O(n))的复杂度有保障

分类讨论有点繁琐

code

T3 遗迹

考虑已知初状态如何得到末状态

从后往前扫来确定末状态,如果一根柱子的长度在后面的末状态出现了那么就把它的长度--

直到他的长度没在后面出现为止

那么我们就发现一根柱子初始长度为j且在最后不存在

当且仅当后面的末状态出现了1-j里面的所有长度

于是我们考虑dp

(f[i][j])表示考虑了([i,2n])内的柱子,当前末状态已经出现了([1,j])的方案数

注意这里(j)应该是极大的

那么我们分情况讨论

这里为方便计数我们认为同高度的两根柱子是不同的

最后除去(2^n)即可

第一种情况(i)没有在最后存在

那么(i)的初始高度必然是在([1,j])里选

这里设后面不存在的个数为(cnt_0)

后面存在的个数为(cnt_1)

那么此时(f[i][j]=f[i+1][j]*(j-cnt_0))

第二种情况(i)在最后存在

那么(i)的初始和最终高度会大于(j)

如果它的最终高度不为(j+1)我们就先不管它了

把它放在后面来算

否则就枚举它和后面的几个存在且没有用过的柱子拼在一起能把(j)扩展(k)

那么此时(f[i][j+k]=f[i+1][j]*(^{cnt_1-j} _{k-1})*h[k-1]*(k+1))

这里的组合数很好理解,就是后面没有用过的中选k-1个柱子

((k+1))是表示如果(i)这根柱子的末状态是(j+1)的初状态种数

显然(j+1)这根柱子两根都没用过都可以选,后面的([j+2,j+k])中的(2(k-1))根柱子用了((k-1))根还剩((k-1))

(h[k-1])则是用(k-1)根柱子使得([1,k-1])都在末状态存在的方案数$

这个需要预处理

(g[i][j])表示用前(i)种柱子填了j个位置的方案数

那么(h[i]=g[i][i])

(g)的转移很显然,枚举第i种用了几个就好了

(g[i][j]=g[i-1][j]+g[i-1][j-1]*2j+g[i-1][j-2]*j*(j-1))

于是就可以在(O(n^3))时间内算出最终答案

code

Day3

T1 星座3

对于一段区间[l,r]考虑其中最高的楼房mid将这个区间分成两半

可以利用st表建出这样一个类似于笛卡尔树的结构

考虑这个x坐标在[l,r],y坐标在[a[mid],n]的矩形

如果这个矩形里没有保留星星

那么就可以分成[l,mid-1]和[mid+1,r]两个区间答案加起来

否则如果保留了某一个就会使得某些区间不能使用

设这个星星的横坐标为x

那么在[l,r]这个区间对应的点的子树中

包含x坐标的区间都是不能选点的

我们发现这在树上是一条链

我们记在区间对应的矩形里的最优值为g

强制不选星星保留记为f

那么就可以树状数组优化dp

如何把星星定位到唯一的一个区间呢

考虑线段树找到左边第一个高于它的楼房,右边第一个高于它的楼房

这两个之间一定是一个区间

时间大概是(O(nlogn))

code

原文地址:https://www.cnblogs.com/deaf/p/13205255.html