直接一點就後綴自動機了。。。c++
注意要開\(map\)存儲狀態轉移git
每次加入一個新的字符就加上新的狀態的子串數量\(len[new]-len[link[new]]\)spa
#include<bits/stdc++.h> using namespace std; #define reg register typedef long long ll; #define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i) #define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i) #define pb push_back template <class T> inline void cmin(T &a,T b){ ((a>b)&&(a=b)); } template <class T> inline void cmax(T &a,T b){ ((a<b)&&(a=b)); } char IO; int rd(){ int s=0; int f=0; while(!isdigit(IO=getchar())) if(IO=='-') f=1; do s=(s<<1)+(s<<3)+(IO^'0'); while(isdigit(IO=getchar())); return f?-s:s; } const int N=1e5+10; int n; int s[N]; map <int,int> trans[N<<1]; int stcnt,lst,len[N<<1],link[N<<1]; void Init(){ link[0]=-1,len[0]=lst=0; rep(i,0,stcnt) trans[i].clear(); stcnt=0; } ll ans; void Extend(int c){ int cur=++stcnt,p=lst; len[cur]=len[lst]+1; while(~p && !trans[p].count(c)) trans[p][c]=cur,p=link[p]; if(p==-1) link[cur]=0; else { int q=trans[p][c]; if(len[q]==len[p]+1) link[cur]=q; else { int clone=++stcnt; trans[clone]=trans[q]; link[clone]=link[q]; len[clone]=len[p]+1; while(~p && trans[p].count(c) && trans[p][c]==q) trans[p][c]=clone,p=link[p]; link[cur]=link[q]=clone; } } ans+=len[cur]-len[link[cur]]; lst=cur; } int main(){ Init(); n=rd(); rep(i,1,n) s[i]=rd(); ans=0; rep(i,1,n) { Extend(s[i]); printf("%lld\n",ans); } }