250520 模拟赛
分数:\(20+0+50=70\)。
被 T1 卡了一上午,写了 \(20\) 暴力还调了半天(应该还有一个得分神秘的骗分做法,但是没交),然后开始想正解,然后发现正解非常的困难,尝试拆了一下式子但是感觉没有什么用。
T2 困难字符串题,看了两眼就走了。后来的后来尝试写爆搜,然后发现样例过不去,开始调,然后发现要是能二十分钟弄出来一个 trie 之类的东西的话,但是写不出来了。(现在感觉可能是当时太饿了。)发现这玩意暴力就是个 SAM 板子。当时咋没写。
T3 被送了 \(50\),关于链的性质,乱胡了一个三个 \(\log\) 的做法,但是不知道对不对,感觉也比较奇怪写不出来了去尝试写 T2 暴力了。早知道不写 T2 了。
总结是能骗多骗,感觉有希望的东西还是要努力写一写。
T1 二维平面上有的点被挡住了然后你要看到最多的点(point)
抽象。
T2 在字符串内选出最多的两两不为后缀的子串并求和(string)
暴力:枚举所有 ? 位置的字符。因为要选出最多不相互为后缀的串,所以要在原串 SAM 的 parent 树上选最多不互相为祖先后代关系的节点,显然答案是叶子节点的数量。时间复杂度 \(O(n2^n)\)。
咕咕咕
T3 单点修改查询模拟在树上做启发式合并后的根节点(dsu)
模拟每次合并的过程,然后建一个类似 kruskal 重构树的东西,对于每次查询就是从 \(x\) 节点出发每次向更大的儿子跳,直到叶子节点的过程。暴力模拟,每次修改后对重构树重链剖分,查询返回链底权值,时间复杂度 \(O(nq)\)。考虑优化。
引理 1:某个节点子树内重心一定在经过此节点的重链上。因为如果重心不在重链上,显然换成其父亲的重儿子更优。
每次找一个子树内的重心,需要找 \(O(\log n)\) 次。考虑如何快速找重心。
引理 2:子树重心的子树权值和至少为原子树权值和的一半。假设当前重心的子树权值和小于原子树权值和的一半,显然换成其父亲不劣。
引理 3:将子树节点按照随便一个 dfs 序展开,子树重心一定是序列带权中位数对应节点的祖先。根据引理 2 可以感性理解。这样可以确定重心在哪条链上,再根据引理 2 倍增即可。
考虑用树状数组维护 dfs 序上的点权,单次查询 \(O(\log n)\),倍增找重心一共是 \(O(\log^2n)\)。总复杂度 \(O(n\log^3n)\),能过。
浙公网安备 33010602011771号