P4070 [SDOI2016]生成魔咒(后缀自动机)
支持在一个字符串后面在线添加一个字符,同时每次询问当前字符串的本质不同子串数量。
后缀自动机好像有一个性质,就是在线添加字符的时候并不会影响link树的形态,只是在link树上新增一个节点?刚开始一知半解...
#include<bits/stdc++.h>
using namespace std;
const int maxn=4e5+100;
int len[maxn],link[maxn];
map<int,int> nxt[maxn];
int sz[maxn];
int tot=1,lst=1;
int n,x;
long long ans=0;
void sam_extend (int c) {
int cur=++tot;
len[cur]=len[lst]+1;
sz[cur]=1;
int p=lst;
while (p&&!nxt[p][c]) {
nxt[p][c]=cur;
p=link[p];
}
if (!p) {
link[cur]=1;
}
else {
int q=nxt[p][c];
if (len[p]+1==len[q]) {
link[cur]=q;
}
else {
int clone=++tot;
len[clone]=len[p]+1;
nxt[clone]=nxt[q];
link[clone]=link[q];
while (p&&nxt[p][c]==q) {
nxt[p][c]=clone;
p=link[p];
}
link[q]=link[cur]=clone;
}
}
lst=cur;
ans+=len[cur]-len[link[cur]];
}
int main () {
scanf("%d",&n);
for (int i=1;i<=n;i++) {
scanf("%d",&x);
sam_extend(x);
printf("%lld\n",ans);
}
}