传送门
没有题解:
后缀平衡树裸题。
由于出题人语文不行,请去讨论区查看正确题意。
下面这份代码就是在错的题意下写了之后改的,所以排序部分非常诡异。
代码:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const
using std::cerr;
using std::cout;
cs int N=5e5+7;
int n;
int fa[N],pre[N],bel[N];char s[N];
namespace SGT{
int siz[N],lc[N],rc[N];
double L[N],R[N];int *bad,rt;
inline double val(int u){return L[u]+R[u];}
inline bool Cmp(int a,int b){
return s[a]<s[b]||(s[a]==s[b]&&val(pre[a])<val(pre[b]));
}
inline bool eq(int a,int b){
return s[a]==s[b]&&pre[a]==pre[b];
}
cs double alpha=0.8;
int ins(int &u,int i,double l=0,double r=1e18){
if(!u){u=i,L[i]=l,R[i]=r,siz[i]=1;return i;}
if(eq(u,i)){return u;}double M=(l+r)*0.5;int res;
if(Cmp(u,i)){
if((res=ins(rc[u],i,M,r))==i){
++siz[u];if(siz[rc[u]]>siz[u]*alpha)bad=&u;
}
}else {
if((res=ins(lc[u],i,l,M))==i){
++siz[u];if(siz[lc[u]]>siz[u]*alpha)bad=&u;
}
}return res;
}
int q[N],qn;
void inorder_dfs(int u){
if(lc[u])inorder_dfs(lc[u]);q[++qn]=u;
if(rc[u])inorder_dfs(rc[u]);
}
int build(int l,int r,double vl,double vr){
if(l>r)return 0;int mid=l+r>>1;double M=(vl+vr)*0.5;
int u=q[mid];L[u]=vl,R[u]=vr;siz[u]=r-l+1;
lc[u]=build(l,mid-1,vl,M);
rc[u]=build(mid+1,r,M,vr);
return u;
}
void rebuild(int &k){
qn=0;inorder_dfs(k);
k=build(1,qn,L[k],R[k]);
}
int Ins(int i){
bad=nullptr;int t=ins(rt,i);
if(bad!=nullptr)rebuild(*bad);
return t;
}
}
struct data{int l,r,t;};
std::vector<data> rg;
int id[N],rk[N];
void work(){
scanf("%d",&n);
for(int re i=2;i<=n;++i)
scanf("%d",fa+i);
scanf("%s",s+1);
for(int re i=1;i<=n;++i){
pre[i]=bel[fa[i]];
bel[i]=SGT::Ins(i);
// cerr<<"bel : "<<i<<" "<<bel[i]<<"\n";
id[i]=i;
}
std::sort(id+1,id+n+1,[](int i,int j){
return bel[i]!=bel[j]&&SGT::val(bel[i])<SGT::val(bel[j]);
});
for(int re i=1,j;i<=n;i=j){
j=i;while(bel[id[j]]==bel[id[i]])++j;
rg.push_back({i,j,bel[id[i]]});
}
std::sort(rg.begin(),rg.end(),[](cs data &a,cs data &b){
return a.t<b.t;
});
for(cs auto &t:rg){
std::sort(id+t.l,id+t.r,[](int i,int j){
return fa[i]==fa[j]?i<j:rk[fa[i]]<rk[fa[j]];
});
for(int re i=t.l;i<t.r;++i)rk[id[i]]=i;
}
for(int re i=1;i<=n;++i){
cout<<id[i]<<" ";
}
}
void file(){
#ifdef zxyoi
freopen("tree_SA.in","r",stdin);
#endif
}
signed main(){file();work();return 0;}