2023.6.24 NOI模拟赛总结

1.时间安排

7:10~10:00

T1:感觉是简单DS,按套路拆成每个元素对每种长度的区间的贡献,写一写就得出来了拆分后的式子,大概是一个区间加等差数列的形式,还需要维护前驱后继。

T2:简单推了一下感觉是和团划分等难的问题,虽然补图传递闭包但是感觉用不上dilworth定理,很奇怪。

T3:看上去很经典的序列问题,但是取模很难处理,放到后面考虑。

先把T1的暴力式子写了,复杂度 \(O(n^2)\),可以过大样例。

一开始写的是用主席树维护前驱后继,区间加等差数列就用普通线段树,因为细节和空间问题调了很久,在9点终于过了所有大样例,运行时间不开O2大概是4s。

之后把主席树换成了set,已经可以跑到1.5s,开O2可以跑到800ms,但是怕大样例并不强,就想着继续卡一卡。

然后把线段树换成了标记永久化,可以跑到1.2s,开O2可以跑到700ms,之后换了zkw,但是效果不佳,就采用了这个版本。

10:00~11:00

看到这数据范围和时间限制之间分块,查询好说,实在是想不出来怎么根号维护修改,就直接暴力,用循环展开优化,时间可以跑到5s左右,开O2甚至只用800ms。

11:00~12:00

仍然没推出来补图传递闭包的作用,写了个暴力。

result:

T1:100 T2:10 T3:60

2.总结

T1:

这题的区间加等差数列实际上是关于下标的一次函数,于是可以开两个树状数组来把每个位置的答案维护成 \(kx+b\) 的形式,树状数组的常数就小的多,就不需要特别注意卡常的问题了。

T2:

不应该把图看成无向图的,看成可以传递闭包的有向图后,原问题实际上就是求偏序集的最小反链覆盖,那么根据dilworth定理就可以转化成最长链,于是如果串 \(a\)\(b\) 的子串就从 \(a\)\(b\) 连一个有向边,求最长链的长度。

暴力 \(n^2\) 是简单的,正解从本质不同的子串这个角度考虑,用sam的节点表示每个串,那么沿父亲边走相当于删除前面的若干字符,沿转移边走就相当于在后面加上一个字符,这个是符合偏序关系的,因为DFA的转移形成的图都是DAG,于是在广义SAM上做一个DAG最长链就可以了,复杂度 \(O(n)\)

需要注意的是,看到无向图的团有时候也要注意本质上有可能是补图的反链,尤其在遇到最小团划分这类的问题。

T3:

序列分块做法是简单的。

针对取模这个问题,可以转化为修改是整块打标记,查询是求在这个整块中加上标记后大于模数的数字个数,这个可以通过排序后二分找到数量,于是只需要支持修改时整块区间打标记,散块暴力重构,查询时散块暴力枚举,整块在排序数组上二分。

设块长为 \(B\),修改是 \(O(BlogB+\frac{n}{B})\),查询是 \(O(\frac{nlogB}{B}+B)\),去 \(B=\sqrt(n)\),得到复杂度 \(O(n\sqrt(nlogn))\)

用归并精细实现可以做到 \(O(n\sqrt(n+m))\),但是很麻烦,而且复杂度和值域相关。

posted @ 2023-06-24 16:16  Displace  阅读(27)  评论(0)    收藏  举报