【详解】树上后缀排序

P5353 树上后缀排序

传送门

后缀数组

因为觉得题解区内的一些后缀数组做法的解释并没有解释到点子上,遂写此题解。

思路

注意这题字符串是从当前节点向上,编号却是从根向下……

我们称一个字符串的大小为这个字符串的值(不考虑编号)的大小,实际大小为按照题目所给判断方式的大小。

倍增构造SA,考虑需要顺序按照哪些关键字排序:(越前面的关键字优先级越高)

  1. 当前字符串的大小。
  2. 祖先字符串的大小。
  3. 祖先字符串的编号大小。
  4. (当前字符串的大小)
    当前字符串的编号大小。

可以将2,3合并,将4前面增加一个1(因为如果比较到了第4关键字,第1关键字必然相等,可以随意添加),如下:

  1. 当前字符串的大小。
  2. 祖先字符串的实际大小(实际为(净大小,编号)的二元组)。
  3. 当前字符串的实际大小(同上)。

这样便不需要额外维护字符串编号的大小了(而且排序的时候也少一个关键字)。

实现

在排序时:需要保证第一个数组是第一关键字,第二个数组是第二关键字的逆

预处理

以字符大小为第一关键字,以当前节点编号为第二关键字,排序即可。

倍增

考虑前一轮已经完成对字符串前1<<k个字符的排序,设顺序为sa大小(不考虑编号)为rk(可两两相同),实际大小(考虑编号)为rkk(两两不同)。

那么,可以顺序按照如下的关键字来排序,得到1<<(k+1)的答案:

  1. 首先比较当前字符串大小的rk
  2. 祖先的实际大小rk2(由rkk得到)。
  3. 当前字符串的sa(实际为rkk[cur]的逆)。

排序时可以先合并后两个关键字,再将得到的与第一关键字合并。

posted @ 2021-05-20 20:35  frank3215  阅读(129)  评论(0编辑  收藏  举报