原意是把sam那一堆做完……
这题还是很sb的,$sum{maxlen(s)-minlen(s)+1}$就是本质不同的子串数量
然后因为suffix link的性质,maxlen[fa[s]]=minlen[s]-1
所以等价于求$sum{maxlen(s)-maxlen(fa[s])}$
这个插入的时候随手做就行了。
类似的sb题还有SDOI2016的生成魔咒
(真是不知道省选考这种题意义何在)
#include<bits/stdc++.h> #define N 1000010 using namespace std; typedef long long ll; int a[N],n;ll ans=0; struct Suffix_Automaton{ int cnt,last,ch[N<<1][26],l[N<<1],fa[N<<1]; Suffix_Automaton(){cnt=last=1;} void ins(int c){ int p=last,np=++cnt;last=np;l[np]=l[p]+1; for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np; if(!p)fa[np]=1; else{ int q=ch[p][c]; if(l[p]+1==l[q])fa[np]=q; else{ int nq=++cnt;l[nq]=l[p]+1; memcpy(ch[nq],ch[q],sizeof(ch[q])); fa[nq]=fa[q];fa[np]=fa[q]=nq; for(;p&&ch[p][c]==q;p=fa[p])ch[p][c]=nq; } } ans+=l[np]-l[fa[np]]; } }sam; inline char read(){ char ch; do{ch=getchar();}while(ch<'a'||ch>'z'); return ch; } int main(){ char c=read(); while(c>='a'&&c<='z')a[++n]=c-'a',c=getchar(); for(int i=1;i<=n;i++)sam.ins(a[i]); printf("%lld ",ans); return 0; }