题解 P5353 【【XR-1】树上后缀排序】
后缀平衡树
很多人说它是在线的后缀数组,其实我感觉它的功能不止于此。
前置知识
替罪羊树
原理
后缀平衡树是一个以字典序为关键字的有序字符串集
-
向字符串集中加入一个长度为
1 的字符串S -
向字符串集中加入字符串
xS ,其中S \in X
所以,如果对一个字符串逆序执行插入操作,它就是严格的“后缀平衡树”,它的中序遍历也就是后缀数组。但其实上,观察这两个操作,它完全可以维护一个有根树森林。
实现
两种插入操作完全可以视为一种。我们考虑要加入一个字符串
显然我们不能
考虑如何进行
对于如何维护平衡,最简单的方法就是使用替罪羊树,注意在重构时要重新赋key值。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1e6 + 5;
const double LIM = 1e16;
const float Alpha = 0.7;
int n;
char S[MAXN];
int fa[MAXN];
int rk[MAXN], sa[MAXN];
namespace SufTree{
double val[MAXN];
int siz[MAXN];
int ch[MAXN][2];
int tr[MAXN], cnt;
int rt;
void Update(int x) {
siz[x] = 1 + siz[ch[x][0]] + siz[ch[x][1]];
}
int Bad(int x) {
return 1.0 * siz[ch[x][0]] > Alpha * siz[x] || 1.0 * siz[ch[x][1]] > Alpha * siz[x];
}
int Comp(int x, int y) {
return S[x] < S[y] || (S[x] == S[y] && val[fa[x]] < val[fa[y]]);
}
void Pia(int x) {
if (!x) return;
Pia(ch[x][0]);
tr[++cnt] = x;
Pia(ch[x][1]);
ch[x][0] = ch[x][1] = 0;
}
void Rebuild(int &x, int l, int r, double lv, double rv) {
if (l > r) return;
int mid = (l + r) >> 1;
double midv = (lv + rv) / 2;
x = tr[mid];
val[x] = midv;
Rebuild(ch[x][0], l, mid - 1, lv, midv);
Rebuild(ch[x][1], mid + 1, r, midv, rv);
Update(x);
}
void Maintain(int &x, double lv, double rv) {
if (Bad(x)) {
// cerr << "*" << x;
cnt = 0;
Pia(x);
Rebuild(x, 1, cnt, lv, rv);
}
}
void Insert(int &x, int idx, double lv, double rv) {
if (!x) {
x = idx;
siz[x] = 1;
ch[x][0] = ch[x][1] = 0;
val[x] = (lv + rv) / 2;
return;
}
if (Comp(idx, x)) Insert(ch[x][0], idx, lv, val[x]);
else Insert(ch[x][1], idx, val[x], rv);
Update(x);
Maintain(x, lv, rv);
}
void Calc(int x) {
if (!x) return;
Calc(ch[x][0]);
sa[++cnt] = x;
Calc(ch[x][1]);
}
void Build() {
for (int i = 1; i <= n; i++) {
Insert(rt, i, 1, LIM);
}
cnt = 0;
Calc(rt);
for (int i = 1; i <= n; i++) rk[sa[i]] = i;
}
}
int main() {
scanf("%d", &n);
for (int i = 2; i <= n; i++) scanf("%d", fa + i);
scanf("%s", S + 1);
SufTree::Build();
for (int i = 1; i <= n; i++) printf("%d ", sa[i]);
return 0;
}
/*
10 5
S 0
Y 1
R 2
E 3
N 4
E 5
A 6
D 7
Y 7
R 9
RY
E
N
S
AY
*/