2023.6.29 NOI模拟赛总结
1.时间安排
7:10~9:30
T1:计算所有的无标号无根树可能有的两点路径和,\(n\) 只有36第一感觉是折半状压。
T2:简单转化一下大概是对于一行加等差数列,求全局min,但是有很多边界情况要讨论。
T3:每次询问给出若干个区间,求区间之间的顺序对数,逆序对相关的问题基本上没有低于根号的,初步会了 \(m_i=2\) 的简单分块。
T1一开始写了个状压,先把两点路径和拆到边上,就变成了和子树大小相关的东西,\(f_{i,s,j}\) 表示 \(i\) 的子树集合是 \(s\),子树大小和是 \(j\),状态是一个bitset,转移是简单的,复杂度非常逆天,但是起码能提供一个暴力打表。
准备继续推怎么折半时突然意识到好像并不需要知道子树的具体形态,甚至不需要知道根,只需要知道无根树大小和子树大小之和,于是设状态是 \(f_{i,j}\) 表示大小为 \(i\) 的无根树子树大小之和是 \(j\) 的bitset,转移枚举当前大小为 \(i\) 的无根树通过某条边拆成 \(j\) 和 \(i-j\),合并bitset。
复杂度大概是 \(O(\frac{n^12}{64})\),一开始 \(n=36\) 1分钟都跑不出来,加了一些优化在开O2的情况下可以跑到4s,实在是卡不到2s以内,就开始打表。
一开始把所有的表都打出来,好家伙直接一个多G,之后只打30以上的表,仍然有500多kb,但是因为答案的值域不大,所以可以把答案转成01串,然后通过字符串的方式卡表长,最后卡到50kb多一点,足够通过了。
9:30~10:30
先把T2的暴力写了,因为样例强度很弱只能相信暴力没写挂。
然后试着写加等差数列,拆成了二阶差分去做转成前缀和,但是对不上大样例,随机了几组小数据都能和前面写的暴力对上,就很寄。
10:30~12:00
先把T3的暴力写了,然后写T3的 \(m_i=2\) 的情况,可以 \(n\sqrt nlogn\) 预处理每个整块相对于其他所有点的顺序对数,那么询问时整块对区间的就可以 \(O(1)\) 回答,剩下的是散块对区间。
一开始写的是主席树,复杂度太炸裂了,咋卡块长都要跑10s以上。
之后想了一下改成了离线后扫描线,ds可以换树状数组,可以跑进2s以内,但是需要vector里面需要放 \(O(n\sqrt n)\) 个元素,场上忘记考虑这个问题,结果MLE了。
result:
T1:100 T2:25 T3:30
2.总结
T2:
场上有点着急了,没有继续分析怎么样拆更好写就去头铁刚大样例了。
首先把式子拆成尽量简介的格式,这样做复杂的分类讨论可能会轻松一些,具体的拆成这样:

先强行让 \(a_i>b_i\) 拆掉绝对值,然后枚举这个点的四个方向,不难发现形成一个菱形。
然后就是一个菱形加,全局求min,但是菱形的两边可能不完整。
先考虑完整的情况,一种方法是拆成和 \(i,j\) 相关的二元一次函数,另一种方法是头铁硬拆二维差分,不想思考的我当然选择了后者
通过打表发现是两段斜着的1和两段斜着的-1,这个可以通过斜着的前缀和来做,也就是先做一遍前缀和求出这四段,然后再做二维前缀和。
然后就是讨论一下边界超过 \(n\) 的情况,等比例位移一下即可。
总之细节非常多。
T3:
shaber题,做不到单根号就没有含金量。
提供一下自己订题时的简单小常数 \(O(n\sqrt nlogn)\),标算虽然有一部分log在根号下面但是大复杂度还是log在外面,所以没有大区别。
首先还是预处理每个整块对于两边的前或后缀顺序对个数,复杂度 \(O(n\sqrt nlogn)\)。
然后考虑对询问根号分治,对于 \(m_i\geq \sqrt{(\sum m_i)}\) 的询问只有根号个,直接暴力做,复杂度 \(O(n\sqrt nlogn)\)。
对于剩下的询问,先枚举所有的整块,然后枚举所有的询问区间,用预处理的数组,做所有的整块对整块和整块对散块,这一部分是均摊 \(O(n\sqrt n)\) 的。
然后是散块对散块,直接按顺序做即可,每个询问区间最多剩下来 \(O(\sqrt n)\) 个元素,所以复杂度均摊 \(O(n\sqrt nlogn)\)。
所有需要的ds只有树状数组,所以理论常数非常小,但是实际表现却刚好卡在时限内过去,可能刻意卡常后能更快一点。

浙公网安备 33010602011771号