标签:ref efi etc main ble class end 插入 后缀
显然可以构造一棵后缀树,将问题转化成了在这棵树上找到两个点\(i,j\),使得\(w_i\bigoplus w_j+ len_{\rm LCA(i,j)}\)最大
于是在树上\(dfs\)的时候启发式合并\(\rm trie\)就好了,发现自己已经菜到不会写\(\rm trie\)了,\(\rm trie\)的插入做到最后一层还是有节点的,得先添加这个节点,之后才能返回
#include<bits/stdc++.h>
#define re register
#define LL long long
const int maxn=2e5+5;
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
std::vector<int> v[maxn];
char S[maxn>>1];
int a[maxn>>1],tax[maxn>>1],A[maxn];
int ch[maxn*25][2];
int len[maxn],son[maxn][26],rt[maxn],fa[maxn];
int n,lst=1,cnt=1,tot,ans;
inline int max(int a,int b) {return a>b?a:b;}
inline int ins(int now,int w,int v) {
if(!now) now=++tot;
if(w==-1) return now;
int u=(v>>w)&1;
ch[now][u]=ins(ch[now][u],w-1,v);
return now;
}
inline int chk(int now,int w,int v) {
if(w==-1) return 0;
int u=(v>>w)&1;
if(ch[now][u^1]) return (1<<w)+chk(ch[now][u^1],w-1,v);
return chk(ch[now][u],w-1,v);
}
inline int merge(int a,int b) {
if(!a||!b) return a+b;
ch[a][0]=merge(ch[a][0],ch[b][0]);
ch[a][1]=merge(ch[a][1],ch[b][1]);
return a;
}
inline void extend(int c,int w) {
int p=++cnt,f=lst;lst=cnt;
len[p]=len[f]+1,rt[p]=ins(rt[p],16,w);v[p].push_back(w);
while(f&&!son[f][c]) son[f][c]=p,f=fa[f];
if(!f) {fa[p]=1;return;}
int x=son[f][c];
if(len[f]+1==len[x]) {fa[p]=x;return;}
int y=++cnt;
len[y]=len[f]+1,fa[y]=fa[x],fa[x]=fa[p]=y;
for(re int i=0;i<26;i++) son[y][i]=son[x][i];
while(f&&son[f][c]==x) son[f][c]=y,f=fa[f];
}
int main() {
n=read();scanf("%s",S+1);for(re int i=1;i<=n;i++) a[i]=read();
for(re int i=n;i;--i) extend(S[i]-'a',a[i]);
for(re int i=1;i<=cnt;i++) tax[len[i]]++;
for(re int i=1;i<=n;i++) tax[i]+=tax[i-1];
for(re int i=1;i<=cnt;i++) A[tax[len[i]]--]=i;
for(re int i=cnt;i;--i) {
int x=A[i];
if(v[x].size()>v[fa[x]].size())
std::swap(rt[x],rt[fa[x]]),std::swap(v[x],v[fa[x]]);
int now=0;
for(re int j=0;j<v[x].size();j++) {
v[fa[x]].push_back(v[x][j]);
now=max(now,chk(rt[fa[x]],16,v[x][j]));
}
rt[fa[x]]=merge(rt[fa[x]],rt[x]);
ans=max(ans,now+len[fa[x]]);
}
std::cout<<ans;return 0;
}
标签:ref efi etc main ble class end 插入 后缀
原文地址:https://www.cnblogs.com/asuldb/p/11414328.html