#CSP202605E2. 绝世好串 - 1e6 测试
绝世好串 - 1e6 测试
根据不同做法,我们设置了一个额外评测链接,仅修改了 $n$ 的范围上限。
目前评测机对于专门卡常数的提交评测比其他 OJ 要慢一点(非卡常的代码性能表现基本差不多),但是依旧满足 2 倍 std 的时间限制,因此时空限制依旧合理,保持不变。有精力的情况下,会持续对时间 2log 以上以及空间 1log 以上的做法出 Hack 数据(至少现有已知的这些做法都卡掉了,在其他较快的 OJ 测了也无法通过)。但是滥用本题评测将会被封号处理。
时间限制: 3.0 秒
空间限制: 1024 MB
题目描述
西西艾弗岛上某实验室设计了一套包含 个字符的字符集,字符从 到 编号。本题中,我们无需关心这些字符具体是什么,只需用整数编号对其进行指代即可。
现有一棵 个节点的简单树,每个节点有一个字符串。初始时,第 个节点的字符串只包含一个编号为 的字符,也就是说 个节点的所有字符构成了字符集 。
你可以对某一个节点进行一次「聚拢」操作:
- 将这个节点的字符串,和所有与它相邻节点的字符串一起进行重排(可以任意决定这些字符串的拼接顺序),重排后合并成一个字符串,作为这个节点的新字符串;所有与它相邻节点的字符串均被清空为空串。
你可以执行任意次操作,但是必须保证:
- 除了第一次操作,每次操作参与的字符串(在执行聚拢操作的节点或邻域节点上的字符串)中一定有一个字符串长度 。
你需要最后将树上所有字符合并到一个字符串里,作为最终串。
求能够得到的字典序最小的最终串。
输入格式
从标准输入读入数据。
第一行包含一个正整数 ,表示树上的点数。
接下来 行,每行包含两个正整数 ,表示树上的一条边。
输出格式
输出到标准输出。
输出一行 个由空格分隔的整数,表示字典序最小的最终字符串。
7
3 5
5 7
3 1
2 5
3 4
6 4
1 2 3 5 7 4 6
样例 1 解释
样例对应的树结构为:

可通过以下 次合法的「聚拢」操作得到字典序最小的最终串:
- 对节点 操作:合并 号点的字符,按升序拼接得
2 3 5 7。此时全树仅有这一个串长度 。(其余参与点均清空,下同) - 对节点 操作:合并 号点。拼接顺序为 ,得到
1 2 3 5 7 4。 - 对节点 操作:合并 号点。拼接顺序为 ,得到
1 2 3 5 7 4 6。
操作结束后,所有字符成功合并为一个字符串,即为答案。
子任务
本题无数据梯度,需要通过全部数据获得所有分数。对于所有测试数据,满足 ,保证输入是一棵合法的树。
提示
本题输入输出量较大,请采用效率较高的输入输出方式。
附录 1
“我要战斗,与所有错误行使力量的人战斗。” / “只有做好了被枪击觉悟的人,才有资格开枪。”——鲁路修《Code Geass》
“不对!所谓觉悟,是把自己的命也押上去。”——蒙奇·D·路飞《ONE PIECE》
“不是因为有胜算。只是因为必须打倒他,所以我就去打倒他,仅此而已。”——黑崎一护《BLEACH》
“我战斗的目的,无论过去还是现在都只有一个,为了我自己的正义。”——斋藤一《浪客剑心》
“即使这样的人生充满伪善,我也会继续坚持成为正义的伙伴!”——卫宫士郎《Fate/stay night UBW》
“我有想守护的东西。那就是,平凡得不能再平凡的日常。”——立花响《战姬绝唱 Symphogear》
“为了保护那些仅靠所谓‘正义’无法保护的东西。”——月读调《战姬绝唱 Symphogear G》
附录 2
对"GPT 話你知": Thoses tasks surpassed by LLMs 的拙劣模仿。
官方题解时间复杂度 、空间复杂度 ,第一版这么冗长(这么长的一坨史山还被其他 AI 当成语料了),后面才简化到 100 多行(而且还是 的)?玩的太差了。不妨来点思考链更简单的做法,还不用在原树上分类讨论下一步走几条边。
题解
记 为闭邻域, 为它的升序串,。固定第一次聚拢中心 ,每次把新儿子中小于大串串首的部分放左边,其余放右边。若依次产生左段 ,答案便是 接上各次右侧输出。取出严格递增短串 ,先比较这些短串的继续前缀,再比较结束点的真实后缀。
相对于根 ,沿原树路径不断刷新 的严格最小值,就得到产生左段的记录中心。把中心按 排序,反复删除最小中心、递归处理剩余分量,构造消元树。沿消元根到 的祖先链,每段同权中心只保留最后一个,正好是 的记录序列。
因此消元边 应输出 中严格小于 的前缀,最后再接完整的 。为每个中心只建一条 字符链,把儿子链接到这个前缀末尾;零长度前缀则共用父链之前的位置。全部闭邻域长度之和只有 ,加一个虚根后,这棵字符树只有 个节点。每个根对应一个终点,根到终点恰好输出它的 。
在字符树上,每轮找当前前沿后继的最小字符,并保留全部同字符后继,得到递增路径 。已经结束的短串留给下一步比较,结束符不参与继续字符的大小判断。再遍历一次,求各根首次失配或提前结束的时刻
ban,并令id[u]为标签在 中的位置,未出现记零。若 全部出现在 中,中心 在 时完成。它完成时仍匹配前缀,就恰好是这一轮的合法结束根。逐轮激活完成中心,用并查集合并相邻中心。
对第 轮结束根所在分量 ,记 为 中最后一个不属于 的位置,没有记零。补完不输出右段的操作后,真实大串就是 。下一继续字符为 ,末轮设为 。
严格胜出可以压成一个阈值。对出现在 中的中心 ,令它的非零邻点位置为 , 为不在整条 中的最小邻点,定义 、。若 不存在,不建立这项贡献。
中心已经收入、剩余块能参与比较、未读首字符小于继续方向,合起来就是 且 。预处理 ,结束根严格胜出当且仅当 。
等价地, 且窗口 被 完全覆盖。完成分量不会覆盖未来字符,所以可以直接维护静态后缀 的覆盖数,令 单调右移。树上两个相邻分量的闭邻域交集只有连接边两个端点,合并时扣重;删除标签时,更新它所在的完成分量,或它各个已完成邻点所在分量。
选出首个严格胜出的结束根,截断 得到准确的 。重新定根,不在这段 中的儿子就是各中心的右载荷。倒扫 的父亲连续段,恢复左记录执行链。建立原父亲依赖与记录链依赖,空载荷优先,其余按最小右首做拓扑排序,连续输出每个任务的完整右段。若一开始 ,直接输出 。
正确性与复杂度
记录与消元。 祖先必须先展开,非记录中心已有记录祖先提供更小串首,只有记录中心会产生左段;独立左目标先处理较大者的交换,使记录按值递减执行。消元树祖先性质由路径最小值归纳得到。同权 时,两中心都在 内;同权祖先链靠前的中心在原树朝根方向还会遇到同权中心,因此不是严格记录,最后一个才保留。对升权边,朝根的原邻点 满足 ,故父链截取的部分排除了 ,恰好是新收入的左段。于是每个终点字符串都精确等于 。
共享与筛选。 每条中心链只有一个接入位置,保留父链继续边及全部儿子分支后仍是一棵树,终点路径没有遗漏。逐轮保留全部最小字符后继,按前缀长度归纳即得精确的短串前沿。完成时刻与首次失配时刻共同精确识别结束根。
首差与覆盖。 已展开中心属于结束根的完成分量。若最后一个尚待实际收入的左字符已经被该分量闭邻域覆盖,唯一路径上的中心都已完成,其右段为空,应继续补完,矛盾。因此空操作对齐后真实大串由最后覆盖缺口确定。中心自身位置与邻点断档给出 ,整条 之外最小邻点的排名给出 ,二者精确描述严格更小的合法右首。对中心取存在量词得到 ,再等价改写为窗口全覆盖。并查集的扣重公式由原树无环保证,静态后缀与当前窗口的交集相同。
结束分支的比较。 更大的真实下一字符立即落败;相等时,确实存在匹配的继续短串,产生相等字符的已暴露中心可以接管:将其未读右块对应到新根块的剩余部分,完整读完此块并补空操作后,完成分量、未读邻点及进入方向对应,后续可以继续逐块匹配。因此继续分支保留不差的完整答案。这个性质保留了“确实存在共同前缀继续分支”的前提,不能只因下一字符仍递增就换根。同轮多个结束根必相邻,否则它们的标签各落在对方左段中,会同时推出 与 ;它们属于同一完成分量,续写相同。所以首个严格胜出的结束根可以返回。
续写。 每个左段来自一个父亲,倒扫 能恢复记录链。父亲边保证暴露,记录链保证左段次序;它们与固定根合法日程相容且无环。就绪空任务提前执行无损,非空任务右首互异,取最小者就是首差最优选择。依次拼接右载荷得到固定根最优答案,再结合选根结论得到全局最优。
消元合并、完成分量更新均为线性次并查集操作;字符树、前沿与失配回放都是线性规模。排序、接入二分、路径压缩并查集及最小堆拓扑排序合计确定性 时间,所有结构合计 空间。
同样的时间空间量纲,完整代码不到 100 行,2.6 KB。出题人出题的时候也没做完的题就是简单。
附录 3
对"GPT 話你知": Thoses tasks surpassed by LLMs 的拙劣模仿。
官方题解和你的 GPT 只能做到 ?玩的太差了。下面给出一个时间复杂度 、空间复杂度 的做法。先走到 ,再把剩下的并查集因子逐项消掉。
题解
记 为闭邻域, 为其升序串,。固定初始中心 ,每次将新儿子中小于串首的部分接到左侧,其余接到右侧,得到 。先提取递增短串 ,再处理根块结束之后的右侧输出。
消元树共享全部短串
固定根的非空左段来自路径上严格刷新 最小值的记录中心,记录按 递减执行。按 构造最小点删除的消元树:删去最小中心,再递归各分量。消元祖先链中的每段同权中心只保留最后一个,就是固定根的记录序列。
消元边 输出 中小于 的前缀,终点 再输出完整的 。为每个中心建立一条邻域字符链,把各消元儿子接到相应前缀末尾,便能共享所有短串。字符总数为 ,加一个虚根得到线性大小的字符树。
逐层取前沿后继的最小字符,并保留全部相同字符的后继,得到路径 。短串终点交给后续比较,结束符不参与继续字符选择。再遍历字符树求每个根的首次失配时刻
ban,记录标签位置id。上述构造可以线性完成:邻表按整数标签转置排序,中心按 入桶;逆序激活时收缩原树边,另存分量的消元根;按 递增查询父链接入位置,每条父链只需一个单调游标。排序、截取和字符扫描都不需要比较数据结构。
首差变成窗口覆盖
闭邻域全部出现在 的中心,在 时完成。该时刻仍匹配前缀,就恰好是合法短串结束根。逐轮激活完成中心,合并其原树相邻分量。
对第 轮结束根所在分量 ,令 为 中最后一个不在 的位置。根块读完并补空右段操作后,当前真实大串为 。比较结束分支是否严格小于下一继续字符 ,末轮取哨兵 。
对已读中心 ,非零邻点位置为 ,整条 外最小邻点为 。定义 、。不存在 就不贡献。中心合法且能给出严格更小字符,等价于 且 ,故预处理 即可。
严格胜出就是 ,也就是 且窗口 被 完全覆盖。维护静态后缀 的覆盖数,让 单调右移。完成分量不含未来字符,所以静态后缀与当前窗口的交集相同。合并两个相邻分量时,闭邻域只重复连接边两端,直接扣重。
下一字符较大的结束分支落败;相等时,存在匹配的继续短串,产生共同字符的完整块可以接管旧分支。首个严格胜出的结束根就是所需根,返回它及准确的 。若 长度已为 ,直接输出。
从比较堆到有效父亲树
重定根后,各中心未出现在 中的儿子构成右载荷,非空右首互异,记为 ;空载荷记零。倒扫 的父亲连续段,恢复记录链。任务图由原父亲边与记录链边组成,目标是最小关键码拓扑序。
数学上给任务赋权 ,空任务为零,令 为终点为 的最大路径权。按 排列非空任务,恰好就是最小就绪序。实现只需要在每个记录点的原父亲和上一记录之间,选出 更大的前驱,形成一棵有效父亲树。
按记录链加入每个新记录的原树祖先新路径。所有旧点都能到达上一记录,故其数值不超过上一记录的 。若基点与 的最高不同位为 ,新路径中记录点之前的最大关键码为 ,则原父亲比上一记录大当且仅当 ,由此决定有效父亲。
只保存每点的出生首差,以及随后每轮最大记录变化的最高不同位 。因为 时 ,旧点当前首差就是出生首差与出生后全部 的最大值。新路径各点只加入一次,每轮的出生首差通过新路径的前缀或后缀最大值线性算出,剩下一个追加式后缀最大值接口。
有效树上,沿根路径维护递减栈:读入关键码时弹掉较小尾部,再追加它,得到截尾签名。每个非空点的签名父亲是最近的严格更大关键码祖先。先删空点,再按关键码递增删除,用最近未删除祖先查询得到所有签名父亲。签名孩子按关键码排序,前序遍历就是最优任务序,依次输出右载荷即可。
先到反阿克曼,再到线性
消元分量、完成分量、最近更大祖先以及单调后缀最大值,都只需线性次集合操作。用按大小合并加路径压缩,语义名字另外保存,得到 时间、 空间。
前三个树分量问题都能进一步用固定树合并:消元与完成过程收缩的是已知原树边,最近更大祖先收缩的是已经完整求出的有效父亲树边。增加永久保留的虚根零,收缩 等价于删除 的标记,查分量就是找最近保留祖先。
取微块大小 ,每块加上唯一外部入口后连通,用一个字保存块内祖先集合和保留点集合。按位与后取最高位,得到块内最近保留祖先;不存在就跳到外部入口。
只有 个外部入口参与宏集合。宏集合用成员直接编号查询,合并时小集合全体改名,并保存祖先侧语义名字。每次跨块循环会合并两个不同宏集合,每个宏成员至多改名 次,所以全部改名量为 。线性次查找与删除的总费用也是 。
后缀最大值单独改成追加式分块 RMQ。块长取 ,块内递减栈用位掩码,整块最大值建稀疏表。只有 个整块,全部表项和构建时间都是 。每次后缀查询由两端的部分块和中间完整块组成,常数时间回答。
正确性与复杂度
短串表示。 固定根规范扩展与独立左目标的交换给出记录次序。消元祖先性质来自原路径最小值;同权中心都邻接同一最小标签,使祖先链只需保留最后一个同权点。对消元边 ,朝根的原邻点 满足 ,因此截取部分恰为左段,不含旧字符。共享字符链保留全部终点路径,前沿逐层保留全部最小字符分支,故 与失配时刻精确。
选根。 完成时刻与前缀匹配条件准确识别根块结束。树上唯一路径保证补空操作后,真实大串由完成分量的最后覆盖缺口确定。邻点断档与未读最小字符给出 ,所以 精确等价于严格胜出,闭邻域扣重又精确实现窗口覆盖。相等接管要求存在实际继续分支;连续处理共同块后两边的未读块及入口对应,能保留不差的完整答案。同轮结束根必相邻、属于同一完成分量,续写相同。因此首个严格胜出的结束根可以返回。
数值排序。 最大路径权沿非空依赖严格增加,所以数值序是拓扑序。若当前最小数值任务为 ,却有关键码更小的就绪 ,则 的最大前驱路径不含 ,与 的最高首差至少在 。加入更低的 不改变首差,仍得到 ,矛盾。空任务通过只传递依赖的逻辑收缩处理。
有效父亲。 上一记录支配全部旧点,新路径关键码未在旧路径出现,故 精确判断哪个前驱更大。单调三点首差公式精确维护后续比较。沿原 DAG 拓扑序归纳,有效树保留每个点的最大路径值,因此保留最优任务次序。
签名排序。 截尾追加总使签名严格增大,保证祖先先于后代。若 , 末项为 ,且新关键码 ,则截尾追加后的 ,共同前缀不会被截掉,首差方向不变。这排除了“还存在更小的就绪任务”,故签名序也是最小就绪序。最近更大祖先正好给出签名前缀,用签名树前序得到完整最优续写。
所有字符链、任务、记录新路径、阈值贡献及边操作都只有线性多个。三处固定树合并采用微块加宏集合的小并大改名,总时间线性;追加式 RMQ 的总构建线性、每次查询常数。所有排序均为整数桶或已有有序邻表扫描。因此算法部分达到确定性 时间、 字空间。
这里采用竞赛中对整数和 位机器字操作的计费方式;十进制文本读写另外按实际字符长度计费。线性并查集的界是整段操作序列的摊还总界,不要求单次查找最坏常数。
附录 2:你跑不过我你信吗?