P4070 [SDOI2016]生成魔咒(字尾自動機)
阿新 • • 發佈:2021-07-15
支援在一個字串後面線上新增一個字元,同時每次詢問當前字串的本質不同子串數量。
字尾自動機好像有一個性質,就是線上新增字元的時候並不會影響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); } }