【CF873F】Forbidden Indices 後綴自動機
阿新 • • 發佈:2017-12-31
出現 scan char ext scanf space brush 長度 最大
【CF873F】Forbidden Indices
題意:給你一個串s,其中一些位置是危險的。定義一個子串的出現次數為:它的所有出現位置中,不是危險位置的個數。求s的所有子串中,長度*出現次數的最大值。
|S|<=200000
題解:板子題啊,沿著pre樹統計一下子樹權值和,然後用mx*權值和更新答案就好了。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn=400010; int n,tot,last; long long ans; char S[maxn],T[maxn]; int ch[maxn][26],pre[maxn],mx[maxn],r[maxn],st[maxn],tb[maxn]; inline void extend(int x) { int p=last,np=++tot; mx[np]=mx[p]+1,last=np; for(;p&&!ch[p][x];p=pre[p]) ch[p][x]=np; if(!p) pre[np]=1; else { int q=ch[p][x]; if(mx[q]==mx[p]+1) pre[np]=q; else { int nq=++tot; mx[nq]=mx[p]+1,pre[nq]=pre[q],pre[np]=pre[q]=nq; memcpy(ch[nq],ch[q],sizeof(ch[q])); for(;p&&ch[p][x]==q;p=pre[p]) ch[p][x]=nq; } } } int main() { scanf("%d%s%s",&n,S,T); int i; last=tot=1; for(i=0;i<n;i++) extend(S[i]-‘a‘),r[last]=‘1‘-T[i]; for(i=1;i<=tot;i++) st[mx[i]]++; for(i=1;i<=tot;i++) st[i]+=st[i-1]; for(i=tot;i>=1;i--) tb[st[mx[i]]--]=i; for(i=tot;i>=1;i--) r[pre[tb[i]]]+=r[tb[i]]; for(i=1;i<=tot;i++) ans=max(ans,1ll*r[i]*mx[i]); printf("%I64d",ans); return 0; }
【CF873F】Forbidden Indices 後綴自動機