[AGC007 E]Shik and Travel
题意
一棵二叉树,定义从根节点出发到每个叶子节点\(i\)可以走出一个字符串\(S_i\),向左为字符'L',向右为字符'R',依次填下来。每个叶子节点上有个权值\(v_i\),权值之间两两不同。现在你可以选择某个节点交换它的左右子树,要求进行最少次数的操作使得对于叶子节点\(a\)和\(b\),\(S_a<S_b\)当且仅当\(v_a<v_b\),这里字符串比较利用字典序。
多组数据,\(1\leq \sum N\leq10^6\)。
分析
考虑这里要做的操作其实就是要把叶子节点排序,我们不难发现这个走出来的字符串对应于字典序实际上相当于叶子节点的顺序,例如排完序后某个节点左子树的\(v_i\)都要小于右子树的。我们观察到,我们需要的实际上只是整块整块子树对应节点之间的一个相对的顺序,也就是说某个节点处需不需要交换和其两个子树内部有没有进行什么交换是没有关系的(和其的祖先更没有关系),我们只需要判定一下这两棵子树内部相当于“一段值”之间能不能通过交换顺序实现有序就可以了,这里记录下子树里面叶子节点\(v_i\)的最大最小值,然后进行简单判定即可。
时间复杂度显然为\(\text O(N)\),即一次对树遍历的操作。
这里需要注意的是一种考虑局部贡献的思想,对于一些有特殊性质的题目,可以发现完全可以将对全体的决策拆成很多局部做,而且还可以很轻易地叠加。