2023.5.31 NOI模拟赛总结

1.时间安排

7:10~9:00

T1:开场看到T1是划分集合最优化方案而且贡献巨难计算,有点想摆,想到8点都没想出来一个复杂度低于指数级枚举的DP做法。

T2:以前nfls集训出过的题,是个扫描线+线段树维护范德蒙德卷积,但是当时没订,这下伏笔了。

T3:与中位数有关的计数DP,可能能胡出来一个 \(m\leq 10\)\(O(nmk^6)\) 的东西,但是我相信状态数非常少。

想T1想到8点没有DP的思路,然后又想了半个小时T2的正解,但是已经忘了正解的推导过程,最后用半个小时把T3的那个离谱的东西实现了,样例能过,造了组 \(m\leq 10\) 的数据,跑的飞快,就不管了,理论35分。

9:00~10:00

把T2的bitset写了,复杂度 \(O(\frac{n^3}{w})\)相信数据够水。

推了推容斥,瓶颈在于求三个矩形两两相交的方案数,发现自己完全不会做,摆了。

10:00~12:00

把T1的状压暴力写了,然后试着写了个贪心,先假设所有点都在第一个集合,然后每次贪心选择能让下一个答案最小的点放到第二个集合,发现居然能过所有样例,先相信。

然后推了一推,本质上需要支持全局-1,当前点到根的链上与当前点 \(w\) 相同的点+1,当前点子树内与当前点 \(w\) 相同的点+1。

现在面临一个抉择,要么冲 3log 树剖+带修树套树,要么写B性质 \(w\) 构成一个排列只需要全局-1,感觉 \(3log\) 太逆天了,而且带修树套树非常难写,就写了后者,理论65分。

result:

T1:60(没注意 \(w\) 范围,RE)T2:30 T3:30(数据出锅了一个点,应该是35)

2.总结

T1:

事实上不需要树套树,有一个小常数 2log 做法是对于每种颜色建一个虚树森林,然后在虚树上跑树剖,维护一个堆表示每种颜色的答案,不太好写。

我是正着做的,正解是考虑倒着做,先考虑所有点都在第二个集合,然后用调整法+分类讨论证明每次如果确定选某种颜色的点,一定是选这种颜色的点形成的虚树森林的若干个根的最值。

于是对于每种颜色建出来虚树森林,开个堆维护当前的虚树根集合,再开个堆维护所有颜色的最优值,删除一个虚树的根把虚树上的所有儿子再加入就好。

不需要真的建出虚树,用记忆化就可以了,复杂度是堆的 1log。

T2:

考虑把每个矩形看做一个点,两个矩形相交就把两个点连一条边,转化成选三个点的没有边的导出子图。

考虑容斥,用所有的方案 \(C_{n}^3\) 减去含有一、二、三条边的。

前两者只需要求出每个点的度数,也就是和这个矩形相交的矩形数量,这个可以简单扫描线。

具体的,考虑矩形相交在 \(l,r\) 上分为两类:\(l_j\leq l_i\leq r_j\)\(l_i<l_j\leq r_i\)

对于前者,考虑在 \(l_j\) 处加入线段 \([u_j,d_j]\),在 \(r_j+1\) 处删除,在 \(l_i\) 计算与 \([u_i,d_i]\) 相交的数量。

对于后者,考虑差分,转化成 \(\leq r_i\) 的减去 \(\leq l_i\) 的,类似的扫描线。

现在考虑第三种情况,三个矩形两两相交,这时候考虑一种做法,在 \(l_i\) 处加入 \([u_i, d_i]\),在 \(r_i+1\) 处删除,求某个时刻有多少对线段与 \([u,d]\) 相交的线段相交。

维护两个数组 \(v1, v2\),加入一条线段 \([u_i,d_i]\) 时,对 \([u_i,d_i]\)\(v1\) +1,对于 \([u_i,d_i)\)\(v2\)+1,删除时类似,那么对于一个查询的答案就是 \(\sum_{i=u}^{d}(C_{v1_i}^2-C_{v2_i}^2)\),这是因为用 \([x,y]\) 处的贡献减去了 \([x,y-1]\) 的贡献,刚好形成一个差分,不重不漏。

于是在线段树上维护 \(C_{x}^2\) 就好,区间下放标记用范德蒙德卷积计算即可。

复杂度 \(O(nlogn)\)

T3:

我的35分DP实际上可以改成 \(O((n+k^5)m)\) 的,具体考虑如果区间内没有-1那么DP值是常数,可以提前预处理,这样需要计算的区间数量是 \(O(k)\) 个,准确来讲是 \(O(klog_3n)\) 个,DP过程是三个数组的背包,可以先合并两个,再合并第三个,复杂度可以从 \(O(k^6)\) 变成 \(O(k^4)\)

考虑这个东西可以先把给定的值排序去重,那么相邻的两个值之间跑出来的DP数组是相同的,唯一不同的是系数,系数是一个 \(x^j(m-x)^k\) 的形式,是个 \(j+k\leq h\) 次多项式,前缀和就是 \(h+1\) 次多项式,用拉插就可以解决了,这个拉插可以做到线性,复杂度变为 \(O(n^2+nk^5)\)

注意到只有把给定的值排序去重后只有 \(O(k)\) 个段是会产生贡献的,考虑 \(-1\) 的数量只会最多让中位数改变 \(O(k)\) 次,可以提前判断这个段是否存在成为中位数的方案,如果能再做DP。

于是复杂度就变成 \(O(nk+k^6)\),用vector卡空间就可以过掉了。

posted @ 2023-06-01 17:28  Displace  阅读(38)  评论(0)    收藏  举报