洛谷 P3804 後綴自動機
阿新 • • 發佈:2018-02-21
自動 thml for 自動機 inline psu efi 數據 pos
題目描述
給定一個只包含小寫字母的字符串SS ,
請你求出 SS 的所有出現次數不為 11 的子串的出現次數乘上該子串長度的最大值。
輸入輸出格式
輸入格式:
一行一個僅包含小寫字母的字符串SS
輸出格式:
一個整數,為 所求答案
輸入輸出樣例
輸入樣例#1:abab輸出樣例#1:
4
說明
對於10\%10% 的數據,|S|<=1000∣S∣<=1000
對於100\%100% 的數據,|S|<=10^6∣S∣<=106
今天上午惡補了一下後綴自動機,發現好像沒有想象中的那麽難,,,,
對於本題來說,我們只要把後綴自動機建出來,然後逆序dfs維護一下非根非葉子的right集合大小*max{}的最大值即可。
#include<bits/stdc++.h> #define ll long long #define maxn 4000005 #define pb push_back using namespace std; int root=1,tot=1,n; char s[maxn]; int f[maxn],ch[maxn][27]; int siz[maxn],las=1,l[maxn]; int a[maxn],c[maxn]; ll ans=0; inline void ins(int x){ int p=las,np=++tot; las=np,l[np]=l[p]+1; siz[np]=1; for(;p&&!ch[p][x];p=f[p]) ch[p][x]=np; if(!p) f[np]=1; else{ int q=ch[p][x]; if(l[q]==l[p]+1) f[np]=q; else{ int nq=++tot; l[nq]=l[p]+1; memcpy(ch[nq],ch[q],sizeof(ch[q])); f[nq]=f[q]; f[q]=f[np]=nq; for(;ch[p][x]==q;p=f[p]) ch[p][x]=nq; } } } inline void build(){ for(int i=0;i<n;i++) ins(s[i]-‘a‘); for(int i=1;i<=tot;i++) c[l[i]]++; for(int i=n;i>=0;i--) c[i]+=c[i+1]; for(int i=1;i<=tot;i++) a[c[l[i]]--]=i; } inline void solve(){ for(int i=1;i<=tot;i++){ int now=a[i]; siz[f[now]]+=siz[now]; if(siz[now]>1&&siz[now]<n) ans=max(ans,siz[now]*(ll)l[now]); } } int main(){ scanf("%s",s); n=strlen(s); build(); solve(); printf("%lld\n",ans); return 0; }
洛谷 P3804 後綴自動機