「题解」P9558 [SDCPC2023] Trie
do_while_true · · 题解
orz negiizhao
自底向上确定每个点的所有出边上挂的字符,那么问题就是比较
这里排序使用归并排序 stable_sort,现在来分析一下复杂度:
单独考虑每一层:在归并两个队头分别为
const int N=200010;
int n,m;
int fa[N],vis[N],col[N],siz[N];
vi eg[N];
void dfs1(int x){
siz[x]=1;
for(auto v:eg[x])dfs1(v),siz[x]+=siz[v];
stable_sort(eg[x].begin(),eg[x].end(),[&](const int &x,const int &y){
function<int(int,int)>cmp=[&](int u,int v){//u<v:1 v<u:-1 u=v:0
if(vis[u]+vis[v]==1)return vis[u]?1:-1;
int len=min(eg[u].size(),eg[v].size());
for(int i=0;i<len;i++){
int t=cmp(eg[u][i],eg[v][i]);
if(t)return t;
}
if(siz[u]==siz[v]){
if(u==x&&v==y)return u<v?1:-1;
return 0;
}
else return siz[u]>siz[v]?1:-1;
};
return cmp(x,y)==1?1:0;
});
int len=eg[x].size();
for(int i=0;i<len;i++)col[eg[x][i]]=i;
}
void solve(){
read(n,m);
for(int i=0;i<=n;i++)vi().swap(eg[i]),vis[i]=0;
for(int i=1;i<=n;i++)read(fa[i]),eg[fa[i]].pb(i);
for(int i=1,x;i<=m;i++)vis[read(x)]=1;
dfs1(0);
for(int i=1;i<=n;i++)putchar('a'+col[i]);
puts("");
}