2023.6.15 NOI模拟赛总结
1.时间安排
7:10~8:30
T1:看上去很奇怪的数据结构,看到 \(max(a_i+a_j,b_i+b_j)\) 第一反应是拆成 \(a_i+a_j>b_i+b_j\) 做数点这类的,但是又删除可能又需要线段树分治。
T2:以前看云浅在u群问过类似的题,暴力和拆一半的fwt拼起来一共有50分,正解记得好像要很毒瘤的分讨构造。
T3:看上去不太难的字符串题,暴力建trie跳父亲的 \(O(nq)\) 居然有60分。
先推了推T1,不删除可以开个主席树,带上删除可以线段树分治,但是很麻烦,预测4k代码量,而且只有60分不太想写。
然后先把T2的暴力写了,能过大样例,稍微处理一下细节就可以写出来拆一半的fwt,可以和暴力拍上。
8:30~9:00
暴力建trie,记录每个区间对应的节点,两个串的lcp可以刻画成lca的深度,于是把贡献放在lca上,记录子树内的关键点数量 \(sz\),答案就是 \(\sum C_{sz}^{2}\),简单好写。
目测上sam需要树剖+分讨,估计是重工业,不想写,就先去搞T1了。
9:00~12:00
还是想直接写正解,推了推要做什么,每个元素有一个出现的时间段,每个询问也是时间段,难道要区间数点?但是不是计数而是max很难处理。
后来想了想可以先按照权值排序,这样相当于建一个下标线段树而不是权值线段树,支持线段树上区间修改区间查询。
以为推对了,开始写,快写完发现不太对啊,我怎么求出每个时刻的答案(根本绷不住)。
发现最坏情况还是 \(O(n^2logn)\) 的,寄。
于是先把暴力写了,没大样例只能先相信没问题。
然后是不删除,怕动态开点常数太大又离线离散化改成普通线段树,能和暴力拍上。
这时候已经11点了,想着写个线段树分治算了,一直调不出来。
一直调到最后,只能相信数据水,把没调出来的线段树分治交了。
result:
T1:35 T2:50 T3:60
(随着难度递增而递增的分数,抽象)
2.总结
T1:
没想到线段树分治没挂,暴力和不删除都挂了,笑死,还是有一些细节没考虑到。
正解考虑还是对权值建线段树,每个白点的权值是 \(a_i-b_i\),黑点是 \(b_i-a_i\),然后按时间维护这个线段树,加入或者删除一个元素,这个可以通过在叶节点维护可删堆解决,在每个线段树上的区间维护当前区间内两家蛋糕满足条件的最小值。
合并答案的时候需要一些分类讨论,讨论蛋糕的来源是黑点还是白点,答案就是全局的最小值,复杂度 \(O(nlogn)\)。
T2:
人类智慧题。
正解就是在FWT的过程中对每一位做这一位对应的变换,\(b_i=0\) 就不变换,\(b_i=1\) 做 FWTOR,\(b_i=2\) 做 FWTAND,\(b_i=3\) 做 FWTXOR,看上去很对,不会严谨证正确性。
T3:
简单SAM题,看大家都是78k的样子,我的做法比较轻工业。
加入操作可以直接二分+hash求出来加入的区间,然后在sam上定位到这个节点,这个是容易的,sam上倍增即可。
到这里其实就可以对parent树进行树剖然后分讨算答案了,分讨的原因在于定位到的节点是包含这个串的,这个串真正的位置可能是在定位到的点到他父亲的转移边上,这个很难受。
考虑一种简单的做法,不妨把这些特殊的边上的点拿出来,然后类似建虚树,虽然树的规模变大了,但是代码非常好写,代价是常数更大。
维护答案一种是我考试时推的维护组合数,就是线段树跑范德蒙德卷积,估计常数大到飞起,更简单的是考虑增量,只算加入/删除这个点后答案会变化多少,不难发现是祖先链所有点的子树大小乘这个点的权值,权值就是到父亲的转移边的长度,当然新建的节点也是需要考虑转移边长度的,都不难处理。
复杂度是树剖线段树复杂度,\(O(nlog^2n)\),跑的比较极限。

浙公网安备 33010602011771号