这道题我首先搞出了一个做法,但是看到题解后发现了一个更优雅的做法。
我的做法(也是官方做法1)就是:先猜一个结论:极大权值消除序列=最大权值消除序列。
这个结论的推论:从任意顺序开始消除,则答案还是一样的。
考虑钦定一个顺序消除,使用一个栈扫描整个序列,则每次最多会删除1个数。时间复杂度O(qn)
分治一下整个序列,在左/右两边维护两个栈l[i],r[i],l[i]表示依次插入mid~i的序列,r[i]同理。
发现消除只在中间产生,所以计算出中间的lcp,哈希维护。
题解的做法是:考虑一个消除树。
这个消除树的建造方法是:
1.如果当前点可以被消除,则跳到父亲节点。
2.如果当前节点不可被消除,则新建一个点x,当前点i->x的边权设为新来的字母。
这棵树有一些优美的性质:
1.这棵树可以被视为一个字典树。
2.一个节点伸出的边的边权互不相同,且如果遇到一个字母c,则现在这个节点x走到的点p的x-b边边权一定为c
3.从l走到r的方式是:记下走到l-1的点,从l-1按照规则走,到r
4.一个字符序列l,r对应这走到l-1的节点->走到r的序列。
根据性质4,每次求一个lca即可。